js内存相关题
- 引用自身
//错误实例
var a = {self : a}; //这样a.self会是undefined
//上面这样等于
var a; //undefined
a.self = a //这时a还是undefined
//正确写法
var a = {};
a.self = a; //这样a.self就等于它自己
- 注意新旧地址
var a = {n:1};
var b = a;
//这一行运行的时候先运行a = {n:2},相当于给了a一个新地址
//再运行a.x = a,相当于把新地址赋给了旧地址上对象一个x属性
a.x = a = {n:2}
//然而有了新地址的a并没有x属性
alert(a.x); // undefined
//b是引用的a的旧地址,所以b有
alert(b.x); // [object,Object]
- 垃圾、垃圾回收
var a = function(){};
var a = null;
/*这样上面那个function因为没有被任何东西引用,所以function占的内存就是垃圾,
会被浏览器回收*/
下面的function是垃圾吗?
var fn = function(){};
document.body.onclick = fn;
fn = null;
// 不是,因为document.body.onclick = fn;还在引用
想要function变成垃圾可写document.body.onclick = null;
若是把页面关了,就相当于document不存在了,于是这时body、onclick、function都是垃圾,浏览器会把它们回收。
DOM相关
- 获取
href
a.href //这样获取href,浏览器会给href加上http协议
a.getAttribute('href') //这样获取的才是href本身
函数相关
- this指向
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出obj,因为转换为 obj.foo.call(obj),this 就是 obj
bar() //打印出window,转换为 bar.call(),由于没有传东西,所以 this 就是 undefined,最后浏览器给你一个默认的 this —— window 对象
function fn (){ console.log(this) }
var arr = [fn, fn2]
arr[0]() // 这里面的 this 是arr
- 作用域
var a = 1;
function f1() {
console.log(a)
var a = 2;
f4.call();
}
function f4() {
console.log(a);
}
f1.call(); //??
// 答案:undefined(f1的console.log)、1(f4的console.log)
var a = 1;
function f1() {
console.log(a)
var a = 2;
f4.call();
}
function f4() {
console.log(a);
}
a=2;
f1.call(); //undefined 2
// html
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
// js
var liTags = document.querySelectorAll('li');
for(var i=0;i<liTags.length;i++){
liTags[i].onclick = function () {
console.log(i);
}
}
//请问点3时,输出6
//因为点击事件发生之前,for已经循环完了
var x = function () {
console.log(a);
};
function y(f) {
var a = 2;
f();
}
y(x) // a is not defined
// 不要受this的影响
- 立即调用的函数表达式(IIFE)
因为JS把function在行首的,一律解释成语句,而语句后不应该出现(),最简单的处理,就是将其放在一个圆括号里面。
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
jQuery
- 和DOM对象的转换
var div = document.getElementById('x') //dom对象
var $div = $('#x') //jquery对象
//jquery转dom
var div = $div[0] //这样jquery就转换成了DOM对象,或div = $div.get(0)
//dom转jquery
var $div = $(div); //这样dom对象div,就转换成了jquery对象
数组去重
- ES5
方法1:
Array.prototype.distinct = function (){
var arr = this,
i,
obj = {},
result = [],
len = arr.length;
for(i = 0; i< arr.length; i++){
if(!obj[arr[i]]){ //如果能查找到,证明数组元素重复了
obj[arr[i]] = 1;
result.push(arr[i]);
}
}
return result;
};
var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];
var b = a.distinct();
console.log(b.toString()); //1,2,3,4,5,6,56
方法二:(递归)
Array.prototype.distinct = function (){
var arr = this,
len = arr.length;
arr.sort(function(a,b){ //对数组进行排序才能方便比较
return a - b;
})
function loop(index){
if(index >= 1){
if(arr[index] === arr[index-1]){
arr.splice(index,1);
}
loop(index - 1); //递归loop函数进行去重
}
}
loop(len-1);
return arr;
};
var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,56,45,56];
var b = a.distinct();
console.log(b.toString()); //1,2,3,4,5,6,45,56
- ES6
set数据结构
function dedupe(array){
return Array.from(new Set(array));
}
dedupe([1,1,2,3]) //[1,2,3]
拓展运算符(…)内部使用for…of循环
let arr = [1,2,3,3];
let resultarr = [...new Set(arr)];
console.log(resultarr); //[1,2,3]