关于javascript中this的那些事
Mar 18, 2016
this是Javascript语言中的一个关键字!(不是变量,也不是属性)它是面向对象编程范例的核心之一。this没有作用域的限制,嵌套函数不会从调用它的函数中继承到this!
this运用的6种场景:
1.如果this所位于的函数被作为方法调用,此时this的值指向调用这个函数的对象
var demo = { speak: "my name is demo!", test: function() { console.log(this.speak); } }; demo.test();//my name is demo!
2.如果this所位于的嵌套函数中被作为函数调用,在非严格模式下,此时this指向全局对象!(运行于浏览器时,指向Windows)
var demo = { test: function() { function inner_test() { console.log(this); } inner_test(); } }; demo.test();//windows
3.如果this所位于的嵌套函数中被作为函数调用,在严格模式下,此时this指向undefined
"use strict"; var demo = { test: function() { function inner_test() { console.log(this); } inner_test(); } }; demo.test();//undefined
4.如果this所位于的嵌套函数中被作为构造函数调用,此时this指向这个新生成的对象
var goble_num = 1; function demo() { this.goble_num = 2; } demo(); console.log(goble_num);//2,此时this指向全局对象 goble_num = 1;//恢复全局变量goble_num var d = new demo(); console.log(d.goble_num);//2 console.log(goble_num);//1
5.如果this所位于的嵌套函数调用了apply或call函数,此时this指向apply或call函数的第一个参数
var num = 1; function demo(arg) { console.log(this.num, arg); } var o = {}; o.num = 2; o.demo = demo; // 用法1: 改变this指向 o.demo.apply();//1, apply()的参数为空时,默认调用全局对象 o.demo.apply(o, ['demo']);//2 ,apply传入 参数数组 o.demo.call(o, 'demo');//2 , call传入 参数列表 // 用法2: 借用别的对象到方法 var Person1 = function () { this.name = 'demo'; } var Person2 = function () { this.getname = function () { console.log(this.name); } Person1.call(this); // 借用Person1的属性和方法,来实现继承 } var person = new Person2(); person.getname(); // demo
6.如果this在HTML的标签中被当做事件绑定回调函数的参数传入 ,此时this指向触发事件的对象 [object HTMLElement]
7.ES5中的bind来为函数绑定this
var obj = { name: 'this demo' } function demo() { console.log(this.name); } var demo1 = demo.bind(obj); // 不立即执行demo,而返回一个以obj为this的新函数demo1 demo1(); // this demo // 手写一个类bind函数的实现 function test (b) { console.log(this.a , b) } test.bind = function() { var testOld = this // 作为方法使用,此时this指向test函数 var newThis = [].shift.call(arguments) // 借用数组的方法,获取第一个参数 return function () { var args = [].slice.call(arguments) // 借用数组的方法,将arguments转换为数组 testOld.apply(newThis, args) } } var test1 = test.bind({ a: 'this a' }) test1('no, this b') // this a no, this b
8.ES6中的 箭头函数 ,默认绑定了执行环境的this,实现this继承
const obj = { a: function() { console.log(this) // 常规写法 }, b: () => { console.log(this) // 按箭头函数定义的方法 }, c: function() { let test = () => { console.log(this) } test() // 可以理解为:执行方式同下面的方法d,默认绑定了this }, d: function() { let test = function () { console.log(this) } test.call(this) } } obj.a() // obj obj.b() // window obj.c() // obj obj.d() // obj // 特性:不能用call方法修改里面的this obj.b.call('abc') // window