JS 原型中的this理解

前面讲过了,在全局作用域下声明的函数或者变量,默认是window这个对象的属性了,前面再议函数时,说过,上下文这个概念跟作用域的概念的区别,上下文是一个目标变量被当成某个对象的属性或者方法时,这里的对象是目标的上下文,我是这么理解的。而this在代码层面上就是时刻指向这个对象了。

内部函数


这里的this怎么会这样呢?可以这样理解,要执行的是f0,所以f0是目标函数,这时候里面可以是这样的:

function f0(){
 // var this = window   这里隐含着一个这样的声明了。
  function f2(){
    console.log(this)
  }
  f2()
} 
f0()

setTimeout setInterval


document.addEventListener('click',function(e){
  console.log(this)
  setTimeout(function(){
    console.log(this)
  },200)
},false)

运行如图:



之前做项目封装的时候,在这个定时器上栽过很多跟头的,因为这个定时器是个独立的函数,不是跟内嵌的一样,因为它运行是异步运行在任务列表里的,我认为在任务队列里的时候它是全局作用域的变量,否则取消定时器不就只能放在它所在作用域里取消它了吗?那如何实时取消操作它呢?当然这里不能再说作用域了,比如这个是相对于变量的存在意义的范畴,而不是作为变量所属的对象研究的上下文。
这里老师给了一个一般性结论:
如果碰到了回调函数,那this基本都变了,否则也不会用回调函数了。

构造函数

上次写原型的时候,写new的作用,第一步就是创建一个空对象,空对象的proto等于原函数的prototype,第二部就是运行这个函数,运行时,函数里的this指向这个空对象,最后把加工了的空对象返回。

作为对象方法调用

var obj = {
  name:'haha',
  printname : function(){
  console.log(this.name)
}
}
obj.printname()  //'haha'

对象的方法调用,这个方法的对象就是这个对象了,this直接指向它喽。
陷阱:



fn是在全局声明的,就是window的属性了,只不过这个赋值的范畴让你迷惑,就是声明加赋值嘛。

DOM绑定事件

除了低版本的bug指向window,事件处理中的this代表事件源DOM对象。

document.addEventListener('click',function(e){
  console.log(this)
  var self = this              //经常用到的技巧,拿不准了,提前把this的指针赋值给一个变量,
//因为默认this这四个字母代表了当下目标变量的上下文,铁打的this,流水的变量。
  setTimeout(function(){
    console.log(this)
    console.log(self)
  },200)
},false)

Function.prototype.bind

bind返回一个新函数,并使函数内部的this为传入的第一个参数。
bind执行时,也就是返回的函数执行时,那个对象作为参数传了进来。换句话说,我们为这个函数设置了新对象。
所有的函数都是Function创造的,在Function.prototype.bind上加一个函数,所有的函数都有bind这个方法了。



它的作用有利于复用函数,而且是在指定的上下文里去运行。注意最后面的括号不要忘了,因为返回的是函数,要执行就要加。



再看看这样呢:

this.say是对的,this就是指的page,这时候,相当于事件被解读状态。但是触发事件运行事件的回调say函数时,里面的this就变了,代表了当前的事件事件节点。
验证一下;

var page = {
  init:function(){
    this.node = document.body
    this.bind()
  },
  bind:function(){
    this.node.addEventListener('click',this.say)
  },
  say:function(){
    console.log(this)
    console.log('haha')
  }
}

page.init()

结果;

那怎么办呢?


var page = {
  init:function(){
    this.node = document.body
    this.bind()
  },
  bind:function(){
    this.node.addEventListener('click',this.say.bind(this))
  },
  say:function(){
    console.log(this)
    console.log('haha')
  }
}

page.init()

那就对于上面那个DOM事件用bind处理一下吧:

document.addEventListener('click',function(e){
  console.log(this)
             
  setTimeout((function(){
    console.log(this)
  }).bind(this),200)
},false)

call ,apply设置this

fn.call(context,x,y,a,b,,,,)
fn.apply(contet,array)
//第一个参数是设置this的对象,剩下的是参数,一个是枚举形式,一个是数组形式。
function sum(){
  var result = 0
  var arg = Array.prototype.slice.call(arguments,0)
  var agu = Array.prototype.sort.call(arguments)
  var max = Math.max.apply(null,arg)       //之前讲过参数的传递,传少了会默认从第一个参数开始匹配,
//第一个是this的指向,必须要设,就设null,否则报错的
  Array.prototype.forEach.call(arguments,function(val){
    result += val
  })
  console.log(result,arg,agu,max)
  return result
  
}
sum(1,4,7,2)

就是简化我们的代码,一般call的处理速度更快。

caller

在函数A调用函数B时,被调用的B会自动生成一个caller属性,指向调用它的函数对象,如果没有被调用,或者并非被其他函数调用,caller= null。

function fn1(){
  console.log(fn1.caller)
  function fn2(){
    console.log(fn2.caller)
  }
  fn2()
}
fn1()

arguments

函数在调用时,传入的参数被加工生产出的一个类数组对象.


callee

当函数被调用时,它的arguments.callee对象会指向这个函数自身。对自己的引用,比如递归。
匿名函数特好用。



var i =1
window.onclick = function(){
  console.log(i)
  if(i<20){
    i++
    setTimeout(arguments.callee,3000)
  }
} //可以试试这个函数,相当于自己设定条件,只要满足了什么,
//它就可以无限调用自身的。可以做监察检测之类,判断状态,,,
//但是严格模式下用不了了,平时玩玩就可以了。

函数变量

  • 实例变量:this,类的实例才能访问到的
  • 静态变量:属性,直接类型对象能访问到的
  • 私有变量:局部变量,当前作用域内有效变量
function A(){
  var a =1      //局部变量
  this.b = 2    //实例变量,必须要创造实例
}
A.c = 3  //属性对象
console.log(a)     //error
console.log(A.b,A.c)   //undefined ,3
var d = new A()
console.log(a)    //error
console.log(d.b,d.c)  //2,undefined

this练习

函数调用的步骤认识

fn.call(context,x,y,,,,)  //任何函数调用都这样的,只不过大多数指向自身的设置为null。
fn(x,y)  === fn.call(undefined,x,y)
obj.child.mesold(x,y) ===obj.child.mesold.call(obj.child,x,y)
function fn(){
 console.log(this)
}
fn()  === fn.call(undefined)    
//如果传的是null,undefined,那么window默认是context,严格模式下写什么就是什么,没window的事儿。
var obj = {
  foo:function(){
    console.log(this)
  }
}
var bar  = obj.foo
obj.foo() === obj.foo.call(obj)  //foo前面是obj,那就是obj
bar()   === bar.call(null)    //bar前面没东西,那就是null
function fn(){
console.log(this)
}
var arr = [fn,fn2]
arr[0]()   ===arr.0.call(arr)

Event中的this

body.addEventListener('click',funcftion hand(){
  console.log(this)
})

this都是由call,apply指定的,要知道this指谁,就要看hand函数前缀是哪个,但是事件是内置的方法,看不了源码,MDN上说,当事件触发时,

hand.call(event.currentTarget,event)  //触发事件的作为this

,,,,

$ul.on('click','li',function(){
  console.log(this)
})      //Jquary?

文档中说的意思:this指向当前正在执行的事件的元素。对直接事件就是绑定的元素。对代理事件,就是当前触发事件的元素。

最后:
不要瞎猜,不清楚就console.log(this).

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容