JS题

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

onClick event in a For loop

// 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]

猜你喜欢

转载自blog.csdn.net/ee2222/article/details/80345150