写该系列文章的初衷是“让每位前端工程师掌握高频知识点,为工做助力”。这是前端百题斩的第14斩,但愿朋友们关注公众号“执鸢者”,用知识武装本身的头脑。
this是javascript中的一个关键字,其使用方法相似于一个变量,是执行上下文中一个重要组成部分。其做用是能够在函数体内部获取当前的运行环境。
每一个函数的this是在调用的时候基于函数的执行环境绑定的,this的指向彻底取决于函数的调用位置。(下面均是在浏览器环境下进行测试的结果)
console.log(this); // window
(1)非严格模式下,this 默认指向全局对象windowjavascript
(2)严格模式下, this为undefinedhtml
function fun() { console.log(this); // window }
对象内部方法的this指向调用这些方法的对象前端
(1)函数的定义位置不影响其this指向,this指向只和调用函数的对象有关;java
(2)多层嵌套的对象,内部方法的this指向离被调用函数最近的对象(window也是对象,其内部对象调用方法的this指向内部对象, 而非window)。数组
const obj = { a: 10, b: 20, add: function () { return this.a + this.b; } }; console.log(obj.add()); // 30 const add = obj.add; console.log(add()); // NaN
const obj = { a: 10, b: 20 }; const prototypeObj = { add: function () { return this.a + this.b; } }; Object.setPrototypeOf(obj, prototypeObj); console.log(obj.add()); // 30
function Fun() { this.a = 10; } const fun = new Fun(); console.log(fun.a); // 10
<button id="testId">按钮</button> const btn = document.getElementById('testId'); btn.addEventListener('click', function() { console.log(this); // <button id="testId">按钮</button> });
内联事件中的this指向分两种状况:浏览器
(1)当代码被内联处理函数调用时,它的this指向监听器所在的DOM元素前端工程师
<button onclick="console.log(this)">按钮</button> // 输出该DOM节点
(2)当代码被包括在函数内部执行时,其this指向等同于 函数直接调用的状况,即在非严格模式指向全局对象window, 在严格模式指向undefinedapp
<button onclick="clickFun()">按钮</button> function clickFun() { console.log(this); // window }
function Fun() { this.a = 10; this.method = function() { setTimeout(function() { console.log(this); // window }, 1000); } } const fun = new Fun(); fun.method();
function Fun() { this.a = 10; this.method = function() { setTimeout(() => { console.log(this); // Fun {a: 10, method: ƒ} }, 1000); } } const fun = new Fun(); fun.method();
除了隐式绑定this的方式,还可以经过显示绑定的方式,经过call、apply、bind方式改变this指向,对于这三者的区别后续将有专门的百题斩去阐述,本节主要进行一波简单使用。
call()
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; console.log(method.call(obj, 3, 4)); // 10
apply()
方法调用一个具备给定this
值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; console.log(method.apply(obj, [3, 4])); // 10
bind()
方法建立一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其他参数将做为新函数的参数,供调用时使用。
function method(val1, val2) { return this.a + this.b + val1 + val2; } const obj = { a: 1, b: 2 }; const bindMethod = method.bind(obj, 3, 4); console.log(bindMethod); // [Function: bound method] console.log(bindMethod()); // 10
扩展
call()
和 apply()
的区别是call()
方法接受的是参数列表,而apply()
方法接受的是一个参数数组;1.若是以为这篇文章还不错,来个分享、点赞吧,让更多的人也看到函数
2.关注公众号执鸢者,与号主一块儿斩杀前端百题。测试