JS的this指向
栏目: JavaScript · 发布时间: 5年前
内容简介:js函数中this是面试官最喜欢考察的,整理一下常用的this指向的知识点。非严格模式和严格模式中this都是指向顶层对象在非严格模式下,普通函数的this指向window
js函数中this是面试官最喜欢考察的,整理一下常用的this指向的知识点。
一、全局上下文
非严格模式和严格模式中this都是指向顶层对象
this.myname = 'xyf' console.log(this) //Window {myname: 'xyf', …}
二、函数上下文
普通函数
在非严格模式下,普通函数的this指向window
var myname = 'xyf' var sayName = function(){ console.log(this === window) // true console.log(this.myname) // 'xyf' } sayName()
这里的 sayName()
相当于调用了 window.sayName()
。在严格模式下,普通函数的this指向undefined
'use strict' var myname = 'xyf' var sayName = function(){ console.log(this === window) // false console.log(this.myname) // 报错,因为this是undefined } sayName()
在ES5中,var会给顶层对象中(浏览器是window)添加属性,而使用let则不会。
let myname = 'xyf' let sayName = function(){ console.log(this === window) // true console.log(this.myname) // undefined } sayName()
对象中的函数
对象中的函数this指向对象本身
var myname = 'outside name' var sayName = function(){ console.log(this.myname) } var person = { myname: 'inside name', sayName: sayName, other: { myname: 'other name', sayName: sayName, } } person.sayName() // 'inside name' person.other.sayName() // 'other name'
将对象中的函数赋值成变量,这样又变成普通函数,this指向顶层对象。
var newSayName = person.sayName; newSayName() // 'outside name'
所以,通过上面我们可以看出来, 函数的定义位置不影响其this指向,this指向只和调用函数的对象有关 。
call、apply、bind改变this指向
通过call、apply、bind可以改变函数this的指向
语法:
fun.call(thisArg, arg1, arg2, ...) fun.apply(thisArg, [arg1, arg2, ...])
thisArg是fun函数在运行时指定的this的值。但是指定的this值不一定就是该函数执行时真正的this值。如果这个函数处于非严格模式下,指定为null和undefined的this值会自动指向全局对象(windows中就是window对象);指定为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象;
var sayName = function(name1,name2){ console.log(this, name1, name2) } // Number {1} 'a' 'b' sayName.call(1, 'a', 'b') // Window { … } 'a' 'b' sayName.call(null, 'a', 'b') // Window { … } 'a' 'b' sayName.call(undefined, 'a', 'b')
apply和call类似。只是参数不一样。它的参数是数组(或者类数组)。
sayName.apply(1, ['a', 'b'])
严格模式下,指向null和undefined的this值还是指向原来的。
var sayName = function(name1,name2){ 'use strict' console.log(this, name1, name2) } sayName.call(null, 'a', 'b') // null 'a' 'b'
bind和call和apply的调用方式相同,第一个值也是修改this的指向,只不过bind返回一个新的函数。
构造函数调用模式
function Dog(name){ this.name = name; console.log(this) } var puppy = new Dog('apple') // Dog {name: "apple"}
由此可知,new操作符调用时,this指向生成的新对象。
原型链中的调用模式
function Dog(name){ this.name = name; } var puppy = new Dog('apple') Dog.prototype.bark = function(){ console.log(this, this.name) } puppy.bark() //Dog {name: "apple"} "apple"
箭头函数调用模式
先看箭头函数和普通函数的重要区别:
- 没有自己的this、super、arguments和new.target绑定。
- 不能使用new来调用。
- 没有原型对象。
- 不可以改变this的绑定。
- 形参名称不能重复。
箭头函数中没有this绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象。 比如:
var name = 'out' var people = { name: 'xyf', sayName: function(){ var arrowFun = () => { console.log(this.name) } arrowFun() }, arrowSayName: () => { console.log(this.name) } } people.sayName() people.arrowSayName()
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
RGB转16进制工具
RGB HEX 互转工具
正则表达式在线测试
正则表达式在线测试