怀化网站排名优化,中国商标注册查询官网入口,外贸网站定制建站,wordpress文章商品模板下载前言
简单阐述 前端的初学者在学习Javascript中this指向的时候经常都会一头雾水#xff0c;尤其是在ES6箭头函数出现之前。 this指向之所以容易让人头疼#xff0c;原因在于 this 是在代码执行时根据环境和情况不同才决定绑定为什么值。 所以本篇文章主要是介绍和总结了各… 前言
简单阐述 前端的初学者在学习Javascript中this指向的时候经常都会一头雾水尤其是在ES6箭头函数出现之前。 this指向之所以容易让人头疼原因在于 this 是在代码执行时根据环境和情况不同才决定绑定为什么值。 所以本篇文章主要是介绍和总结了各种情况下的this指向如果文中有写的不对的地方或者明显错误还请不吝指出互相交流。如果对你有帮助也请不要吝啬手中的点赞~谢谢
在开始之前还是需要介绍this的一些基础知识具体如下
this 是javascript中的一个关键字并非是一个变量。this 关键字指向的是一个对象而指向哪个对象或者是这个对象的值是什么取决于使用(调用)的方式和环境。this 指向的值是可以通过手动方式去改变的比如call、bind、apply方法。this 在严格模式和非严格模式下也会有差别。
this的作用
从某些角度来说开发中我们没有this也是有解决方案的但是如果真的没有this会让我们编写代码十分不方便。例如 // 如果没有this我们更改了obj的命名 // 那么下面的obj.name 都需要进行修改var obj {var name malongeating: function() {console.log(obj.name 吃东西)}studying: function() {console.log(obj.name 学习)}} this的指向 在多数情况下this出现在函数中正常开发通常都是在函数中使用this。 所有的函数在被调用时都会创建一个执行上下文FEC这个上下文中记录着函数的调用栈、AO对象等;this也是其中的一条记录;函数在调用时JavaScript会默认给this绑定一个值this的绑定和定义的位置(编写的位置)没有关系this的绑定和调用方式以及调用的位置有关系 this绑定方式1:默认绑定
独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用这样this就是默认绑定
this是在运行时被绑定的
// 案例1 默认绑定
function foo() {console.log(this)
}// 案例2 默认绑定
function test1() {console.log(this)test2()
}function test2() {console.log(this)test3()
}function test3() {console.log(this)
}
test1()// 案例3 默认绑定
function bar() {func()
}var obj {name: malong,foo: function() {console.log(this)}
}bar(obj.foo)
this绑定方式2:隐式绑定
必须在调用的对象内部有一个对函数的引用(比如一个属性)如果没有这样的引用在进行调用时会报找不到该函数的错误正是通过这个引用间接的将this绑定到了这个对象上调用方式是通过某个对象进行调用的隐式绑定
// 案例1 隐式绑定
function foo() {console.log(this)
}var obj {name: malong,foo: foo
}obj.foo()// 案例2 隐式绑定
function bar() {console.log(this)
}var obj1 {name: malong1,bar: bar
}var obj2 {name: malong2,obj1: obj1
}obj2.obj1.bar()// 案例3 隐式绑定
function baz() {console.log(this)
}var obj3 {name: malong,foo: baz
}var fn obj3.foo;
fn()this绑定方式3:显示绑定
bind 形参第一个参数是对象第二个参数是列表返回值是一个函数。call 形参第一个参数是对象第二个参数是列表apply形参第一个参数是对象第二个参数是数组 通过call绑定this function foo() {console.log(this)}foo.call(window)foo.call({name: malong})foo.call(123)如果我们希望一个函数总是显示绑定到一个对象上而不用向上面那样写多次 function foo() {console.log(this)}var obj {name: 123}var baz foo.bind(obj);baz()this绑定方式4:new绑定 JavaScript中的函数可以当做一个类的构造函数来使用也就是使用new关键字。 function Person(name) {console.log(this)this.name name
}var person new Person(malong)this的绑定过程 创建一个新的对象将构造函数的作用域赋值给新对象(构造函数.prototype 对象.__ proto__)执行构造函数中的代码this绑定在这个步骤完成返回这个对象内部有一个隐式的 return this
this绑定优先级
new 显示绑定(apply,call,bind) 隐式绑定 默认
扩展【一】this规则之外
无视显示绑定规则
function foo() {console.log(this)
}var obj {name: malong
}foo.call(obj)
foo.call(null)
foo.call(undefined)var baz foo.bind(null)
baz()
间接函数引用
function foo() {console.log(this)
}var obj1 {name: obj1,foo: foo
};var obj2 {name: obj2
}obj1.foo();
(obj2.foo obj.foo)();
箭头函数
箭头函数没有this它的this由运行时外层作用域的this决定箭头函数没有arguments箭头函数不能new var name window;var obj {name: obj,getData: function() {// 会默认绑定所以这里的this是 objsetTimeout(() {console.log(this)}, 100)}}// 如果getData也是一个箭头函数那么this会是windowobj.getData() 扩展【二】this面试题 var name windowvar person {name: person,sayName: function() {console.log(this.name);}};function sayName() {var sss person.sayName;sss();person.sayName();(person.sayName)();(b person.sayName)();}sayName()var name window;var person1 {name: person1,foo1: function () {console.log(this.name)},foo2: () console.log(this.name),foo3: function () {return function () {console.log(this.name)}},foo4: function () {return () {console.log(this.name)}}}var person2 { name: person2 }person1.foo1();person1.foo1.call(person2);person1.foo2();person1.foo2.call(person2)person1.foo3()()person1.foo3.call(person2)()person1.foo3().call(person2)person1.foo4()()person1.foo4.call(person2)()person1.foo4().call(person2)var name windowfunction Person(name) {this.name name;this.obj {name: obj,foo1: function () {return function () {console.log(this.name)}},foo2: function () {return () {console.log(this.name)}}}}var person1 new Person(person1)var person2 new Person(person2)person1.obj.foo1()()person1.obj.foo1.call(person2)()person1.obj.foo1().call(person2)person1.obj.foo2()()person1.obj.foo2.call(person2)()person1.obj.foo2().call(person2)