this的用法(二)-箭头函数+面试题

箭头函数与普通函数的this

严格模式下的普通函数this为undenfied,非严格模式是window;箭头函数的this是定义时所在的this

箭头函数this指向注意事项

箭头函数体内的this对象,如果包裹在函数中就是函数调用时所在的对象,如果放在全局中就是指全局对象window。并且固定不会更改。换句话说内部的this就是外层代码块的this

下面是对比分析普通函数和箭头函数中this区别

// 普通函数
function foo() {
  setTimeout(function() {
    console.log(‘id:‘, this.id);
  });
}

var id = 21;
foo.call({ id: 42 }); //21
//注意定时器,此时this指向window
// 箭头函数
function foo() {
  setTimeout(() => {
    console.log(‘id:‘, this.id);
  }, 100);
}

var id = 21;
foo.call({ id: 42 }); //42
// 上面的匿名函数定义时所在的执行环境就是foo函数,所以匿名
//函数内部的this执向始终会和foo函数的this执向保持一致,不会更改,如同下面的这个案例
function foo() {
  setTimeout(() => {
    console.log(‘id:‘, this.id);
  }, 100);
}

var id = 21;
foo(); //21(没有用call)

如果不使用 ES6,那么这种方式应该是最简单的不会出错的方式了,我们是==先将调用这个函数的对象保存在变量 _this== 中,然后在函数中都使用这个 _this,这样 _this 就不会改变了。

var name = "windowsName";
var a = {
 name : "Cherry",
 func1: function () {
  console.log(this.name)
 },
 func2: function () {
  var _this = this;
  setTimeout( function() {
   _this.func1()
  },100);
 }
};
a.func2()  // Cherry

这个例子中,在 func2 中,首先设置 var _this = this;,这里的 this 是调用 func2 的对象 a,为了防止在 func2 中的 setTimeout 被 window 调用而导致的在 setTimeout 中的 this 为 window。我们将 this(指向变量 a) 赋值给一个变量 _this,这样,在 func2 中我们使用 _this 就是指向对象 a 了。

call的作用就是将foo函数的执行环境从window改成对象{id: 42}

==定时器==的作用就是延迟执行当前函数的外部执行环境,无论有没有设置延迟时间

普通函数解释:定义时this指向函数foo作用域,==但是在定时器100毫秒之后执行函数时,此时this指向window对象==

箭头函数解释:this始终指向定义时所在对象,也就是始终指向foo作用域

进一步分析this

var handler = {
  id: ‘123456‘,

  init: function() {
    document.addEventListener(‘click‘,
      event => this.doSomething(event.type), false);
  },

  doSomething: function(type) {
    console.log(‘Handling ‘ + type  + ‘ for ‘ + this.id);
  }
};
handler.init()// Handlingclickfor123456

箭头函数的this始终指向handler,如果是普通函数,this指向document

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

面试题

下面的面试题一、二、四都设计到引用问题,如果不是很好理解还可以理解成在 es5 中,永远是this 永远指向最后调用它的那个对象。

面试题一

this.x = 9;    // this refers to global "window" object here in the browser
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();
// returns 9 - The function gets invoked at the global scope

// Create a new function with ‘this‘ bound to module
// New programmers might confuse the
// global var x with module‘s property x
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81

retrieveX只是getX函数的引用,也就是只是getX的一个指针(getX的另一个指针是module.getX),所以retrieveX还是指向getX函数本身的

和上面类似的案例,下面的func只是函数引用,所以即使在函数内部,还是执行的函数本身,不受词法作用域限制(箭头函数则受限制)

document.getElementById( ‘div1‘ ).onclick = function(){
    console.log( this.id );// 输出: div1
    var func = function(){
        console.log ( this.id );// 输出: undefined
    }
    func();
};
//修正后
document.getElementById( ‘div1‘ ).onclick = function(){
    var func = function(){
        console.log ( this.id );// 输出: div1
    }
    func.call(this);
};
function foo() {
    console.log( this.a );
}

var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };

o.foo(); // 3
(p.foo = o.foo)(); // 2

面试题二

var A = function( name ){
    this.name = name;
};
var B = function(){
    A.apply(this,arguments);
};
B.prototype.getName = function(){
    return this.name;
};
var b=new B(‘sven‘);
console.log( b.getName() ); // 输出:  ‘sven‘

面试题三

确实,许多包中的函数,和许多在JavaScript语言以及宿主环境中的内建函数,都提供一个可选参数,通常称为“环境(context)”,这种设计作为一种替代方案来确保你的回调函数使用特定的this而不必非得使用bind(..)。

举例来说:

function foo(el) {
    console.log( el, this.id );
}

var obj = {
    id: "awesome"
};

// 使用`obj`作为`this`来调用`foo(..)`
[1, 2, 3].forEach( foo, obj ); // 1 awesome  2 awesome  3 awesome

面试题四

明确绑定 的优先权要高于 隐含绑定

function foo() {
    console.log( this.a );
}

var obj1 = {
    a: 2,
    foo: foo
};

var obj2 = {
    a: 3,
    foo: foo
};

obj1.foo(); // 2
obj2.foo(); // 3

obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2

new绑定的优先级高于隐含绑定(new和call/apply不能同时使用,所以new foo.call(obj1)是不允许的,也就是不能直接对比测试 new绑定 和 明确绑定)

原文地址:https://www.cnblogs.com/chaimi/p/10259245.html

时间: 2024-11-05 19:43:48

this的用法(二)-箭头函数+面试题的相关文章

es6(二) 箭头函数

var f = () => 5;// 等同于var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; var sum = (num1, num2) => { return num1 + num2}; // 等同于var sum = function(num1, num2) { return num1 + num2;}; 原文地址:https://www.cnblogs.com/geekjsp/p/98

ES6 => 箭头函数

箭头函数ES6一个非常有用的新特性,我这里小小的总结一下用法: 箭头函数相当于直接return一个值,当没有参数时,可以这么写: var f = () => 0; // 上面这句话相当于 var f = function(){ return 0;} 当有一个参数时: var f = num => return num; // 上面这一句相当于 var f = function(num) { return num;} 当有两个或以上的参数时,要用括号并用逗号分隔开: var f = (a,b)

箭头函数的使用用法(一)

1 //箭头函数的一个好处是简化回调函数 2 //箭头函数没有参数,就使用圆刮号代表参数部分: 3 var f = () =>5; 4 console.log(f()); 5 //两个参数的情况,代码块只有一条语句,可以省略{} 6 var f = (a,b)=> console.log(a+b); 7 f(1,3); 8 //两个参数的情况,代码块只有一条语句,且有return语句:可以省略{}和return: 9 var f = (a,b)=>a + b; 10 console.lo

ES6箭头函数基本用法

``` window.onload = function(){ alert(abc); } //箭头函数 window.onload = ()=>{ alert("abc"); } // 如果只有一个参数圆括号可以省 let play = function(num){ alert(num*2); //24 } play(12); let play = num => { alert(num*2); //100 } play(50); //如果只有一个return 花括号可以省

javascript基础修炼(8)——指向FP世界的箭头函数

一. 箭头函数 箭头函数是ES6语法中加入的新特性,而它也是许多开发者对ES6仅有的了解,每当面试里被问到关于"ES6里添加了哪些新特性?"这种问题的时候,几乎总是会拿箭头函数来应付.箭头函数,=>,没有自己的this , arguments , super , new.target ,"书写简便,没有this"在很长一段时间内涵盖了大多数开发者对于箭头函数的全部认知(当然也包括我自己),如果只是为了简化书写,把=>按照function关键字来解析就好了

箭头函数和Buffer对象

一.箭头函数 普通函数1 var add = function (a, b) { return a + b; } 普通函数2 function add (a, b) { return a + b; } 箭头函数 var add = (a, b) => a + b; 如果函数内部只有一句返回值,连return都不用写了,如果里面执行的语句比较多,就用{ }括起来 var add = (a, b)=> { console.log("这是箭头函数"); return a + b;

深入理解this机制系列第三篇——箭头函数

× 目录 [1]痛点 [2]解决 [3]基本用法[4]回调函数[5]注意事项 前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将介绍ES6新增的内容——箭头函数 痛点 对于闭包的痛点在于,闭包的this默认绑定到window对象,但又常常需要访问嵌套函数的this,所以常常在嵌套函数中使用var that = this,然后在闭包中使用that替代this,使用作用域查找的方法来找到嵌套函数的this值 var a = 0;

ECMAScript6箭头函数ArrowFunction"=>"

一.说明 ECMAScript6可以用箭头"=>"定义函数.x => x * x或(x) => {return x * x;}与匿名函数function(x){return x * x;}相等. 二.示例 2.1 没有参数的箭头函数 var f = () => 9; console.log(f()); //9 2.2 一个参数的箭头函数 var f = x => x * x; console.log(f(3)); //9 var f = x => {

es6箭头函数讲解

es6箭头函数的用法 箭头函数是es6的一种函数的简写方法. 如下: var f = v = > v; //等同于 var f = function(v){ return v; } var sum = (num1,num2) => num1+num2 ; //等同于 var sum = function(num1,num2){ return num1+num2 } [1,2,3].map(function (x) { return x * x; }); // 箭头函数写法 [1,2,3].ma