文章目录

  • JavaScritp 中的 this
    • 总结一句话(永真给的信)
    • 默认绑定(指向少主window)
    • 严格模式(变若之子)
    • 隐式绑定(苇名弦一郎)
    • 隐式丢失(赤鬼 + 鬼庭形部雅孝)
    • 显式绑定(樱龙,白蛇)
    • Dom节点中的this(杂兵)
    • new
    • 箭头函数(另类)
    • 补充
      • 执行上下文
      • 字面量

JavaScritp 中的 this

总结一句话(永真给的信)

大雪纷飞,永真在井上面丢垃圾一封信,信上写着如下内容:

谁最终调用,this 就指向谁。

那么如何理解永真写的话呢?请接着往下看~


默认绑定(指向少主window)

我(this)的职责就是保护指向 少主,少主喜欢用window玩游戏,姑且叫少主window吧。

  • 只狼听从了义父之前的命令,好好保护少主,所以this指针(只狼 )默认绑定(跟随 )的是 window(少主 )
console.log(this);      // window
  • 少主活了几百年,还那么年轻,而且会的东西很多 少主还会a函数,写全局函数的话,也是指向的 window
function a() {console.log(this);
}
a()                     // window
//实际上是  window.a(); 我们可以展开window看看

  • 少主还会做日晷,沙漏等小工具,用来做定时器, 定时器是window(少主 )的方法,所以this也会指向window
// setInterval 也是 window 下的方法
setInterval(function () {console.log(this);     // window
}, 1000)

严格模式(变若之子)

为了追寻长生不老,山上的僧人开始作妖,严格实验了好多小孩,最后就一个小女孩活了下来,成了变若之子(假的皇子)

  • 严格模式下的this指向 undefined(因为是假的皇子,所以就undefined了)
function a() {"use strict";console.log(this);
}
a()                     // undefined
console.log(this);

补充:什么是严格模式
简单来说就是为了更好的规范 JavaScript 语言的书写,具体请参考阮一峰的严格模式详解。

隐式绑定(苇名弦一郎)

情景:我们带着皇子一路小跑,走出隧道,只见弦一郎在堵门,(简介,游戏名《只狼》,第一个BOSS的名字)

开门见山!!先来打苇名弦一郎

var name = '我是全局name'
function fn() {var name = '我是fn';console.log(this.name);
}
var objA = {name:'我是objA',showA:fn
}
var objB = {name:"我是B对象",showB:objA
}
objB.showB.showA()

请问最终打印的是什么呢?这里我先不告诉你们答案,先跟着我一步一步往下走~

分支1:没打过弦一郎(没做对 ):失去手臂,等待佛雕师(作者 )给你安义肢(讲解 )。
分支2:打过弦一郎:同样失去手臂(不要怪我卑鄙!我叫屑一狼),等待佛雕师…
战果:经验 +0,金币 -0,金钱 -0,HP -0,失去真手臂

次日:看到淡淡的油灯光亮,发现自己躺在破旧寺庙的草席上,并且获得了义肢。
战果:获得义肢,HP +100

来看一下栗子(苇名城杂兵,经验怪 ):

function fn() {console.log(this);
}
var obj = {show: fn
};
obj.show();       // {show: ƒ}
// this 指向的关键在于是谁最终执行的

成功忍杀看懂了这个 :金钱+5,经验+5

第二个栗子(苇名城杂兵,经验怪 ):

function fn() {console.log(this);
}
var obj = {show: fn()      // 因为fn才最终执行者,括号代表执行!而 fn 是 window 下的函数
};
obj.show;       // window

成功忍杀:HP+5,金钱+5,经验+5
获得少主给的:伤葫芦,楔丸

此时来到了苇名城 城邑外围 城门道,遇到了第一个boss(河源田直盛)

function fn() {console.log(this.name);
}
var objA = {name:'我是A对象',showA:fn
}
var objB = {name:"我是B对象",showB:objA
}
objB.showB.showA()       // 我是A对象
// 为啥指的是objA呢?
// 你要清除是谁最终调用的fn,是不是objA里才有fn啊,最终调用的也是objA!所以指向就是objA。

成功忍杀看懂了这个 :HP+10,金钱+10,经验+10
获得技能:识破

总结:以上例子可以说明,this的指向跟函数写在哪里没啥关系,关键在于最终调用者是谁

隐式丢失(赤鬼 + 鬼庭形部雅孝)

情景:来到了被锁住的赤鬼。发现兜里没有月隐糖,也没有喷火器,没关系,有闪避+突刺,超级逃课打法。

var name = '我是全局name';
var obj = {name:'我是obj的name',fn:function () {console.log(this.name);}
}
var xxx = obj.fn;
xxx();      // 我是全局name
// 这里为什么是全局name呢
// 因为xxx是最终调用者,而xxx属于window,所以this指向的是window

成功忍杀:获得佛珠,忍者之药理知识•甲
失败:死,(少主的龙血之力,无尽复活 )

接着来到下一关

情景:来到了苇名城 正门外城区,遇到鬼庭形部雅孝,不慌,追的驴的尾巴,砍就完事儿了,逃课

var name = '我是全局name';
var obj = {name:'我是obj的name',fn:function () {console.log(this.name);}
}
function xxx(param) {// 2. 然后在这里执行函数param();// 相当于 window.param()
}
// 1. 此时我把函数体当成参数传递进去了
xxx(obj.fn)     // 我是全局name

成功忍杀:战斗记忆:鬼庭形部雅孝(攻击力强化),机关筒(义手强化工具)。
失败:死,(少主的龙血之力,无尽复活 )

接着到了火牛关

情景:火牛血厚,建议买鞭炮(前面的都看懂了 )

var name = '我是全局name';
var obj = {name:'我是obj的name',fn:function () {console.log(this.name);}
};
var obj1 = {name:"福山润"
};obj1.xxx = obj.fn;
obj1.xxx();     // 福山润

成功忍杀:佛珠,忍者药理·乙。
失败:死,减一半的¥

显式绑定(樱龙,白蛇)

我们可以通过call(干柿子 )、apply(米 )和bind(樱龙之泪 )方法更改指针的指向(不同结局)。

// 显示转换
var objA = {name: "aaa"
};
var objB = {name: "bbb"
};
var objC = {name: "ccc"
};
var name = '我是全局name';
function fn() {console.log(this.name);
}
fn();               // 我是全局name
fn.call(objA);      // aaa
fn.apply(objB);     // bbb
fn.bind(objC)();    // ccc

成功忍杀枭,樱龙,白蛇:获得樱树枝,樱龙之泪,鲜柿子,月隐糖
失败:死,(少主的龙血之力,无尽复活 ),金钱 -1/2

某些方法也可以显式的更改指针,比方说forEach

var obj = {name:'铃木雅之'
};
var arr = [1,2,3,4];
arr.forEach(function () {console.log(this.name);     // 4 * 铃木雅之
},obj)

越到后期,游戏所需要的技巧就越高,熟练度也就越重要,(不我就是平a格挡流 )
显式绑定的优先级 大于 隐式绑定的优先级,显式>隐式>默认

var objA = {name:'aaa',fn:function () {console.log(this.name);}
}
var objB = {name:'bbb'
}
// 前面的是objA.fn() ,隐式绑定,省略了括号,
// 后面的call()是显示绑定
// 当显式隐式都存在的时候,显式优先级更大
objA.fn.call(objB)      //bbb

Dom节点中的this(杂兵)

发现个小胖子,他跟同伴走丢了,他想要我给他找彩色风车…

其实这个跟之前讲的蛮像的,我就在这里再重复一下叭

<body><div class="btn">点我</div>
</body>
<script>function show(){console.log(this);}document.querySelector('div').addEventListener('click', show);// <div class="btn">点我</div>document.querySelector('div').addEventListener('click', show());// window
</script>

成功忍杀:卧槽小胖子好可怜的,别杀了,骗到商人那里打扫战场
失败:良心受到谴责嗯~ o( ̄▽ ̄)o

new

来到了苇名之底 毒沼,狮子猿 new 出一个小狮子猿,二打一,太难了

function Person() {// 1. 刚开始这里的this指向的是 window// 因为这是函数啊this.name = '堺雅人'
}
// 2. 然后通过new方法改变了 this 指向
var p = new Person();console.log(p.name);

成功忍杀:战斗记忆:无首狮子猿,佛珠*2,血刀术(使用不死斩断绝不死后获得)
失败:死,减一半的¥

箭头函数(另类)

来到了苇名城 城邑外围 城门道,看到个没有头的家伙,无首,尼玛打了一架,被戳了菊花,屏幕上出现了:菜

取决于:外层(上层)作用域中的this,和他本身没有关系

var name = 'www';
function fn() {// 这里就是箭头函数上层作用域// 这里的 this 指向 windowconsole.log(this.name);return () => {console.log(this.name);}
}
var objA = {name:'aaa'
};
var xxx = fn();        // www
xxx();                 // www

成功忍杀:哼将之降灵
失败:死,减一半的¥

var name = 'www';
function fn() {// 这里就是箭头函数上层作用域// 这里的 this 通过 call 方法指向了 objAconsole.log(this.name);return () => {console.log(this.name);}
}
var objA = {name:'aaa'
};
var xxx = fn.call(objA);        // aaa
xxx();                          // aaa

情景:最后来到了苇名城主城 贮水城区,弦一郎喝了变若(弱) 水,剑圣苇名一心想要实现他儿子的最后的愿望,就是守护这片土地,于是重返战场…

  • 箭头函数中的this它既是吃软饭的,也很专一
var name = 'www';
function fn() {// 吃软饭的箭头函数this:一直跟随着上层作用域 // 这里就是箭头函数上层作用域console.log(this.name);return () => {console.log(this.name);}
}
var objA = {name:'aaa'
};
var objB = {name:'bbb'
};
// 此时xxx就是箭头函数
var xxx = fn.call(objA);        // aaa// 我这时修改箭头函数的指向,然并卵
// 箭头函数中的this很专一,取决于外层作用域的指向
xxx.call(objB);                 // aaa
  • 如果想改箭头函数的this,那么只能修改上层作用域的this,比方说上面的例子
// 只有修改上层作用域的this,才能改变箭头函数的this
var xxx = fn.call(objb);        // bbb// 即使是修改了箭头函数的指向也没用
xxx.call(objA);                 // bbb

成功忍杀:战斗记忆:剑圣 苇名一心,秘传·龙闪(技能)。
失败:死,我死了200多回hhhh。
通关,赶快去救小皇子~


补充

执行上下文

执行上下文是指 函数调用时 在执行栈中产生的变量对象,这个变量对象我们无法直接访问,但是可以访问其中的变量、this对象等。

let fn, bar; // 1、进入全局上下文环境
bar = function(x) {let b = 5;fn(x + b); // 3、进入fn函数上下文环境
};
fn = function(y) {let c = 5;console.log(y + c); //4、fn出栈,bar出栈
};
bar(10); // 2、进入bar函数上下文环境

每次函数调用时,执行栈栈顶都会产生一个新的执行上下文环境,JavaScript引擎会以栈的方式来处理它们,这个栈,我们称其为函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶就是当前处于活动状态的正在执行的上下文,也称为活动对象(running execution context,图中蓝色的块),区别与底下被挂起的变量对象(执行上下文)。

字面量

用于表达源代码中一个固定值的表示法

this:它到底指向哪里!箭头函数的this又是啥?相关推荐

  1. ES6-6 - this指向、箭头函数基本形式、rest运算符

    一 chrome断点调试 观察函数调用栈 // 25min var x = 1; function foo(x, y = function () { x = 2; console.log(2) }) ...

  2. javascript箭头函数和this的指向问题

    箭头函数 下面两代码等价: const fun1 = function(x){return x*x;}const fun = x => x*x; function换成=>,放在参数和函数体 ...

  3. 关于箭头函数中this指向问题

    对于箭头函数中的this指向问题一直困扰我很久,查阅文章现在终于弄懂了. 先上一段代码: var user="Absorbed-22";let person={user:" ...

  4. 箭头函数 改变this指向

    1.箭头函数 <div>我是div</div><script>const oDiv = document.querySelector('div');// 普通函数o ...

  5. js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

    壹 ❀ 引 工具猴-免费在线工具-在线工具箱- 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安 ...

  6. ES5-拓展 箭头函数的this、this的优先级

    让内部函数的this指向和父函数的this,可以显示改变this指向,也可以使用箭头函数 箭头代替了function关键字 箭头函数内部没有this指向,箭头函数的this是稳定引用父作用域的.因为它 ...

  7. 箭头函数和普通函数有什么区别?

    箭头函数和普通函数有什么区别? 1:写法不一样 2:普通函数存在变量提升的现象 3:箭头函数不能作为构造函数使用 4:两者this的指向不同 5:箭头函数的arguments指向它的父级函数所在作用域 ...

  8. ES6精解:箭头函数

    基本用法 在ES6中允许使用 => 来定义函数,如下: var f = a => a;console.log(f(1)); //1 就等同于 var f = function(a){ret ...

  9. ES6中箭头函数解释

    箭头函数 任何可以书写匿名函数的位置,都可以书写箭头函数 箭头函数将会绑定this为函数书写位置的this值 模块化(nodejs带来的模块化) 没有模块化的世界:全局变量污染,难以管理 常见的模块化 ...

最新文章

  1. (C++)1045 快速排序 非满分
  2. html 自动跳转5秒,html 实现5秒倒计时跳转首页
  3. 智能摄像头——小觅智能摄像头
  4. 可以改动的option组件_uni-app WebView 组件通信
  5. android 软键盘的收回
  6. STM32 通用定时器基本原理
  7. android仿高德地图透明黑字,Android 仿高德地图可拉伸的BottomSheet
  8. 家谱树(信息学奥赛一本通-T1351)
  9. java 多线程初入2
  10. 【FLink】FLink学习遇到的好文章
  11. PAT A1007 动态规划
  12. hdu 2837 Calculation
  13. Windos下的UPD服务器端的C++实现
  14. 腾讯开源 GFP-GAN 代码
  15. chrome去广告插件 去掉百度热搜
  16. 云起实验室:ECS数据管理实践-备份与恢复
  17. 积水成渊——数据中心用水效率分析
  18. RocketMQ消费失败重试机制分析
  19. 豆瓣电台WP7客户端 开发记录4
  20. java replica set_kubernetes ReplicaSet的简单使用

热门文章

  1. 段码LCD驱动芯片(ic)数据资料-VK1072/1088/1621
  2. Tensorflow声纹识别说话人识别
  3. 高项论文练习——论项目的风险管理
  4. 2012诺亚方舟中国号船票正式销售!
  5. 【C语言篇】C预处理器和C库
  6. librdkafka线程CPU百分百问题分析
  7. SS210L-ASEMI低压降贴片肖特基二极管SS210L
  8. 把虚拟机当服务器设置密码,VMware Workstation如何创建加密虚拟机
  9. 程序员修炼之道系列 | 使用曳光弹找到目标
  10. 老板,我想申请加薪~