一、对this的产生原因分析和了解
1.this指的是函数运行时所在的环境(即调用的对象)。2.JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系
二、this绑定详解
this 实际上是在函数被调用时发生的绑定,它指向什么地方完全取决于函数在哪里被调用。
1.默认绑定
function foo(){var a = 1 ; //局部变量console.log(this.a);}var a = 10; //全局变量foo(); //window.foo()
2.隐性绑定
var a = 10; //全局变量function foo(){var a = 1 ; //局部变量console.log(this.a);}var obj = {a : 20,foo : foo}obj.foo(); //window.obj.foo()
3.显示绑定apply,call,bind 这个三个函数都是改变this指向
(1)callvar box=document.getElementById('box')box.onclick = function(){console.log(this) //指向box元素function boxFn(params1,params2,params3){console.log(this)}boxFn()boxFn.call(this,1,2,3) //call改变this指向,将this指向box元素}
(2)applyvar applayObj1={name:'张三'}var applayObj={name:'李四',applayFun(param1,param2,param3){console.log(this.name)}}var applayfun2=applayObj.applayFunapplayObj.applayFun() //window.applayObj.applayFun()applayfun2.apply(this,[1,2,3]) //window.applayfun2.apply(this,[1,2,3])applayfun2.apply(applayObj1,[1,2,3]) //window.applayfun2.apply(applayObj1,[1,2,3])
(3)bindvar title='全局title'var applayObj1={name:'张三'}var bindObj={title:'改变this',bindFun(){console.log(this)}}bindObj.bindFun()var aa=bindObj.bindFunaa()aa.bind(applayObj1)()
4.new 绑定
new出来的对象有以下新特性:
(1)创建一个新对象。(2)把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型)(3)将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)(4)返回新对象。(底层运行机制return返回一个新对象)
var blogA='123'function blog(){this.blogA='456'this.blogFn=function(){console.log(this.blogA)}}var newblogObj=new blog()newblogObj.blogFn()console.log(newblogObj)
三、箭头函数的this绑定
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
var a=12function foo(){this.a=13return ()=>{console.log(this.a)}}let newFoo=new foo()newFoo()var b='666'function foo2(){console.log(this)return ()=>{console.log(this.b)}}var baz=foo2()baz();
(2)箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域
function Timer() {this.s1 = 0;this.s2 = 0;console.log(this)// 箭头函数setInterval(() => this.s1++, 1000); //箭头函数没有this,它的this来自绑定时所在的作用域 即外部代码块的this// 普通函数setInterval(function () {this.s2++; //this为window}, 1000);}var timer = new Timer();setTimeout(() => console.log('s1: ', timer.s1), 3100)setTimeout(() => console.log('s2: ', timer.s2), 3100)
(3). 箭头函数this不可修改
var obj = {b : 999}var b='666'function foo2(){console.log(this)return ()=>{console.log(this.b)}}var baz=foo2()baz();baz.call(obj)
四、this指向与继承
//示例function Parent (name,sex){this.name = name;this.sex = sex;}//添加原型方法Parent.prototype.show = function(){console.log("姓名:" + this.name + "性别" + this.sex)}//声明函数继承 Parent的函数 并添加自己的函数function Worker(name,sex,job){//通过call方法改变Parent的this指向console.log(this)Parent.call(this,name,sex)this.job = job;}//此时wk里既有Parent的函数属性 又有了Worker函数的属性Worker.prototype=Parent.prototypevar wk = new Worker("小明","男","程序员")console.log(wk.name);console.log(wk.sex);console.log(wk.job);wk.show()
