理解js中的函数调用和this
概述
这是我看typescript的时候看引用资源看到的,原文在这里:Understanding JavaScript Function Invocation and "this",我简单地总结一下记下来供以后开发时参考,相信对其他人也有用。
机制
js中的函数调用机制是这样的:
- 建立一个表argList,从索引1开始塞入函数的参数。
- 表的索引0的值是thisValue。
- 把this赋给thisValue,然后调用func.call(argList)。
说这么多,其实就是想说明,函数调用f(x,y)其实就是f.call(this, x, y)的语法糖。内部是通过f.call(this, x, y)来调用的。
可以看到,虽然f(x,y)里面没有this,但是f.call(this, x, y)里面有this,所以非常好理解为什么函数调用中会有this了。
那么this是从哪里来的呢?当f(x,y)没有调用者的时候,this自动被赋值为window;当f(x,y)有调用者的时候,this被赋值为指向调用者。
例子
举几个实例感受一下:
//例子1
function hello(thing) {
console.log(this + " says hello " + thing);
}
hello.call("Yehuda", "world"); //输出Yehuda says hello world
//例子2
function hello(thing) {
console.log(this + " says hello " + thing);
}
//相当于hello.call(window, "world");
hello("world"); // 输出[object Window] says hello world
//例子3
function hello(thing) {
console.log(this + " says hello " + thing);
}
let person = { name: "Brendan Eich" };
person.hello = hello;
//相当于hello.call(person, "world");
person.hello("world"); //输出[object Object] says hello world
注意:我们这里不是strict mode。
更优雅的写法
有时候,我们希望函数没有调用者,但是this却不指向window对象。有以下2种优雅的解决方案:
箭头函数
es6里面定义了箭头函数,不只是为了简化函数的写法,而且还有这么一条有用的规定:箭头函数的this不会随调用者的不同而变化,它的this永远是被定义的函数域中的this。
//不用箭头函数
let person = {
hello: function(thing) {
return function() {
console.log(this + " says hello " + thing);
}
}
}
let helloTest = person.hello('world');
helloTest(); //输出[object Window] says hello world
//使用箭头函数
let person = {
hello: function(thing) {
return () => {
console.log(this + " says hello " + thing);
}
}
}
let helloTest = person.hello('world');
helloTest(); //输出[object Object] says hello world
需要注意的是,需要用一个function()把箭头函数包裹起来,因为如果不这样的话,它被定义的函数域是window。
bind
用箭头函数有点麻烦,我们可以这么写一个bind函数达到效果。
let person = {
hello: function(thing) {
console.log(this + " says hello " + thing);
}
}
let bind = function(func, thisValue) {
return function() {
return func.apply(thisValue, arguments)
}
}
let boundHello = bind(person.hello, person);
boundHello('world'); //输出[object Object] says hello world
es5给所有Function封装了上面的bind方法,所以我们只需要这么写:
let person = {
hello: function(thing) {
console.log(this + " says hello " + thing);
}
}
let boundHello = person.hello.bind(person);
boundHello('world'); //输出[object Object] says hello world
这就是bing()方法的来历0.0
理解js中的函数调用和this的更多相关文章
- 图文结合深入理解 JS 中的 this 值
图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...
- 深入理解JS中的对象(三):class 的工作原理
目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...
- 深入理解Js中的this
深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 如何更好的理解js中的this,分享2段有意思的代码
关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...
- 深度理解js中var let const 区别
首先要理解js中作用域的概念 作用域:指的是一个变量的作用范围 1.全局作用域 直接写在script中的js代码,在js中,万物皆对象,都在全局作用域,全局作用域在页面打开时创建,在全局作用域中有一个 ...
- 如何理解js中的this和实际应用中需要避开哪些坑
this是什么 this就是函数内部的关键字 看下面例子理解js中的this // 例子1 function fnOne () { console.log(this) } 'use strict' f ...
- 深入理解JS中的对象(二):new 的工作原理
目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...
- 理解js中私有变量
私有变量在js中是个什么概念.当下我的认识是var所定义的变量,实际可以理解为属性和方法,或者单单是临时存储器,不归属任何对象. 一个声明函数: function a(){ var v = &quo ...
随机推荐
- 自定义模块和grains
一.自定义模块 saltstack有很多模块,模块的源码文件是在salt项目的:salt/modules.py; salt linux-node2-computer sys.doc 查看有哪些mo ...
- [转]jquery.form.js的ajaxSubmit和ajaxForm使用
参考 http://www.cnblogs.com/popzhou/p/4338040.html 依赖的脚本文件 <script src="../Javascript/jquery-1 ...
- 大数据入门到精通6---spark rdd reduce by key 的使用方法
1.前期数据准备(同之前的章节) val collegesRdd= sc.textFile("/user/hdfs/CollegeNavigator.csv")val header ...
- c# devexpress 多文档界面
学习记录 https://blog.csdn.net/qq_25473787/article/details/81208894?utm_source=blogxgwz0
- 【Nodejs】Nodejsの環境構築
参考URL:http://www.runoob.com/nodejs/nodejs-install-setup.html Windowにインストールする方法を紹介します. ▲ダウンロードURL:htt ...
- 如何访问dashed filename
第一关:boJ9jbbUNNfktd78OOpsqOltutMc3MY1 第二关:CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9 cat <- 第三关:如何访问spaces i ...
- ABP框架 配置权限、本地语言文件、左侧菜单项
1.Framework.Core>Authorization>PermissionNames.cs 这里新增权限项 namespace Framework.Authorization { ...
- Java Token的原理和生成使用机制
在此之前我们先了解一下什么是Cookie.Session.Token 1.什么是Cookie? cookie指的就是浏览器里面能永久存储数据的一种数据存储功能.cookie由服务器生成,发送给浏览器, ...
- centos 7安装java开发环境
https://jingyan.baidu.com/article/29697b91660672ab20de3c15.html 自带版本是有问题的~
- poj2240
一个关于套利的题,就是判断是否有正环,我这里是用的SPFA,只要判断出来一种货币初始为1,最后变得大于1就代表是正环,要注意一下最后对vector的清空,当时从1开始清空,导致wa了两次,找了半天,尽 ...