摘要:构造函数例子例子中,因为构造函数的指向构造出来的实例,所以是用构造出来的对象,那么就是指向。构造函数中要注意的一点是默认情况下,构造函数是没有,但是非要加一个的话。
this
this对于初学 JS 的新人来说,是一道坎,看到this就晕头晕脑,脑容量一下不够用了。
先来说下判断this结论
this是函数调用时call的第一个参数
this只有在函数执行的时候才能被确定,实际指向调用它那个对象(上一级)
先来看下函数常用的几种调用方式
fn(a,b) fn.name(a,b) var f = fn.name; f(a,b) fn.call(undefined,a,b) fn.apply(undefined,[a,b])
上面三种调用方法对于新人很熟悉,而对后面两种方法比较陌生,自然也就弄不明白this含义了。
改写下函数的调用方式就会发现这两种是等价的,回到上面说的结论,call的第一个参数是this,a、b才是传进去的参数。
fn(a,b) === fn.call(undefined,a,b) === window.fn.apply(window,[a,b])
明白了这点,大部分的this就不难判断了,新人在判断this时只需改写函数调用方式就能知道this指向了。
this例子下面方法中暂且不讨论严格模式,this的指向
例子1:
var user = "window" function fn(){ var user = "object"; console.log(this.user); //windwow } fn(); //改写 window.fn.call(window)
fn是全局对象window的方法
例子2:
var user = "window" var obj = { user:"object", fn:function(){ console.log(this.user); //object } } obj.fn(); //改写 obj.fn.call(obj)
这里的fn是被obj调用的,所以fn内部的this指向obj内部的user。
你可能会有疑惑了,这里是不是可以改写成window.obj.fn.call(window),往下看
例子3:
var user = "window" var obj = { user:"object", fn:function(){ console.log(this.user); //object } } window.obj.fn(); //改写 window.obj.fn.call(window.obj)
先看下面例子
例子4:
var user = "window" var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //function } } } obj.fn1.fn2(); //改写 obj.fn1.call(obj.fn1)
例子3中正常情况下都是把window给省略的,这里写出来是为了和例子4做对比。
假设例子4中obj对象是不是window下的方法,而是和window平级(实际不存在这种假设,容易理解)。
这里是链式调用,this的最终指向是调用它的上一层对象fn1,但是不能改写成obj.fn1.call(fn1),只有window可以省略。
例子5:
var user = "window" var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //window } } } var a = obj.fn1.fn2; a() //改写 window.a.call(window)
先看下面例子
例子6:
var a = {user:"window"} var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //window } } } obj.fn1.fn2.call(a);
看到例子5和例子6是不是已经晕了。
例子5中,var a = obj.fn1.fn2只是赋值,并没用执行,而真正执行的时候,a是window下的方法,所以fn2内部的this指向window下的user。
例子6中,call的第一个参数是a,那this肯定指向a的user,因为显示绑定优先级高于隐示绑定。
那你可能要问什么是显示绑定,什么是隐示绑定呢?
obj.fn() //隐示绑定 obj.fn.call(obj) //显示绑定
也就是说你改写后的调用就是显示绑定。
new构造函数例子7:
function Fn(){ this.user = "object"; } var a = new Fn(); console.log(a.user); //object
例子7中,因为构造函数的this指向构造出来的实例,所以a是用new构造出来的对象,那么this就是指向a。
构造函数中要注意的一点是:默认情况下,构造函数是没有return,但是非要加一个return的话。
如果return的是引用类型值,那么构造函数的this就指向return的对象
如果return的是基本类型值,那么构造函数的this就指向构造出来的实例化函数
this基本应用就是这些,做一些实操练习巩固一下
this实操实操1:
function X(){ return object = { name:"object", f1(x){ x.f2() //② 改写 options.f2.call(options) }, f2(){ console.log(this) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //③ 运行这个this,打印 options 函数 } } var x = X(); x.f1(options); //① 改写 object.f1.call(object,options)
看到this就马上改写,不改写就做,肯定错。
分析
首先把x.f1(options)改写object.f1.call(object,options)
x.f1(options)调用object对象内部f1方法,把options函数作为参数传入,所以 object内部f1(x)中的x是options函数
f2内部的this指向options
实操2:
function X(){ return object = { name:"object", f1(x){ x.f2.call(this) //② 这里是显示绑定,改写 options.f2.call(object) }, f2(){ console.log(this) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //③ 运行这个 this 打印 object } } var x = X() x.f1(options) //① 改写 object.f1.call(object,options)
分析
首先把x.f1(options)改写object.f1.call(object,options)
f1内部的this指向object
把x.f2.call(this)改写options.f2.call(object),这里的.call(this)是显示指定
f2内部的this就是object
实操3:
function X(){ return object = { name:"object", options:null, //③ options = options f1(x){ this.options = x //② 改写 object.options = options this.f2() //③ 改写 object.f2.call(object) }, f2(){ this.options.f2.call(this) //④ 显示绑定,改写 object.options.f2.call(object) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //⑤运行这个 this,打印 object } } var x = X() x.f1(options) //① 改写 object.f1.call(object,options)
分析
首先把x.f1(options) 改写object.f1.call(object,options)
f1内的this指向object,options作为参数传进来
把this.options = x改写object.options = options,同时也把this.f2()改写称object.f2()
把this.options.f2.call(this) 改写object.options.f2.call(object),.call(this)是显示绑定
f2内部的this就是object
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/107912.html
摘要:大名鼎鼎的闭包面试必问。闭包的作用是什么。看到闭包在哪了吗闭包到底是什么五年前,我也被这个问题困扰,于是去搜了并总结下来。关于闭包的谣言闭包会造成内存泄露错。闭包里面的变量明明就是我们需要的变量,凭什么说是内存泄露这个谣言是如何来的因为。 本文为饥人谷讲师方方原创文章,首发于 前端学习指南。 大名鼎鼎的闭包!面试必问。请用自己的话简述 什么是「闭包」。 「闭包」的作用是什么。 首先...
摘要:说明最近看到这样一段代码问三行的输出分别是什么觉得有点意思,和大家一起来聊聊。说到这里,这道题基本上可以解决了,希望大家能听明白我上面说的话,下面的就简单了。 说明 最近看到这样一段代码 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:说明最近看到这样一段代码问三行的输出分别是什么觉得有点意思,和大家一起来聊聊。说到这里,这道题基本上可以解决了,希望大家能听明白我上面说的话,下面的就简单了。 说明 最近看到这样一段代码 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:说明最近看到这样一段代码问三行的输出分别是什么觉得有点意思,和大家一起来聊聊。说到这里,这道题基本上可以解决了,希望大家能听明白我上面说的话,下面的就简单了。 说明 最近看到这样一段代码 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
阅读 1181·2021-09-22 15:24
阅读 2285·2019-08-30 15:44
阅读 2613·2019-08-30 10:55
阅读 3354·2019-08-29 13:25
阅读 1638·2019-08-29 13:09
阅读 1391·2019-08-26 14:05
阅读 1378·2019-08-26 13:58
阅读 1984·2019-08-26 11:57