一、对this的产生原因分析和了解
代码语言:javascript复制1.this指的是函数运行时所在的环境(即调用的对象)。
2.JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系
二、this绑定详解
this 实际上是在函数被调用时发生的绑定,它指向什么地方完全取决于函数在哪里被调用。
1.默认绑定
代码语言:javascript复制 function foo(){
var a = 1 ; //局部变量
console.log(this.a);
}
var a = 10; //全局变量
foo(); //window.foo()
2.隐性绑定
代码语言:javascript复制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指向
代码语言:javascript复制 (1)call
var 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元素
}
代码语言:javascript复制 (2)apply
var applayObj1={
name:'张三'
}
var applayObj={
name:'李四',
applayFun(param1,param2,param3){
console.log(this.name)
}
}
var applayfun2=applayObj.applayFun
applayObj.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])
代码语言:javascript复制 (3)bind
var title='全局title'
var applayObj1={
name:'张三'
}
var bindObj={
title:'改变this',
bindFun(){
console.log(this)
}
}
bindObj.bindFun()
var aa=bindObj.bindFun
aa()
aa.bind(applayObj1)()
4.new 绑定
new出来的对象有以下新特性:
代码语言:javascript复制(1)创建一个新对象。
(2)把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型)
(3)将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
(4)返回新对象。(底层运行机制return返回一个新对象)
代码语言:javascript复制 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对象,就是定义时所在的对象,而不是使用时所在的对象。
代码语言:javascript复制 var a=12
function foo(){
this.a=13
return ()=>{
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,绑定定义时所在的作用域,而不是指向运行时所在的作用域
代码语言:javascript复制 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)
代码语言:javascript复制(3). 箭头函数this不可修改
代码语言:javascript复制 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指向与继承
代码语言:javascript复制//示例
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.prototype
var wk = new Worker("小明","男","程序员")
console.log(wk.name);
console.log(wk.sex);
console.log(wk.job);
wk.show()