Comments (15)
@beiatisi 这跟作用域完全没关系。
@cdswyda 我觉得你的回答完全不对。箭头函数本身根本就没有this,需要在上下文中查找,表现出来就是对this透明;而普通函数是有this的,默认为undefined,通过对象点号调用时赋值this为点号前的对象。可能你连我想要问什么都没看明白。
我仔细想了一下,自己尝试回答一下自己的问题:
之所以字段中的箭头函数能绑定对象的this,应该是和javascript引擎的class语法实现有关。
class Animal extends BaseClass {
constructor() {
//构造函数的执行过程大概如下:
let animal = {};
animal.__proto__ = Animal.prototype;
super.constructor.call(animal);
初始化字段(字段属于animal,而不是Animal.prototype)
用户自定义初始化语句
return animal;
}
}
引擎在初始化字段过程中,对箭头函数,会用animal进行替换,导致绑定this。使用函数重写Animal如下:
function Animal(){
let animal = {};
animal.__proto__ = Animal.prototype;
//如果Animal是继承来的,还需要调用原型链上的构造函数
//Animal.prototype.__proto__.constructor.call(animal);
animal.name = 'animal';
animal.age = 17;
animal.sayName = ()=>console.log(animal.name); //因为是字段,可以确定属于animal,因此可以直接绑定
return animal;
}
Animal.prototype.sayAge = function(){
console.log(this.age); // 属于原型链上的方法,不能直接确定到某个对象
}
Animal.prototype.__proto__ = BaseClass.prototype; //继承
let tom = new Animal();
let [sayName, sayAge] = [tom.sayName, tom.sayAge];
sayName(); //输出animal
sayAge(); //出错,this为undefined
from blog.
@ChaosGT 用 babel 把上面你写的这段代码编译到 ES5 看一下就能明白了
省略掉无关编译结果,下面这段是你疑惑的解答应该:
var Animal = function Animal(name, age) {
var _this = this;
_classCallCheck(this, Animal);
_defineProperty(this, "sayName", function () {
console.log(this.name);
});
_defineProperty(this, "sayAge", function () {
console.log(_this.age);
});
this.name = name;
this.age = age;
};
注意两个_defineProperty 的回调函数内对于 this 的使用方式。一个是直接用了 this,一个用了构造实例的闭包,所以一个 this 会丢失(成为undefined),而另一个不会。
结合「箭头函数不具有自己的 this,它的 this 永远是定义时包裹它的代码块的 this」,就可以理解为什么 ES6 编译到 ES5 是这样的实现。其实还是作用域、执行上下文、闭包的问题。
from blog.
// 方式二
class B {
print = () => {
console.log('print b');
}
}
有个小细节,上面这种写法ES6里面应该没有吧,应该只是静态属性的提案中的写法,在使用babel时,如果plugins中只有transform-es2015-classes没有transform-class-properties的话,会报错的。
from blog.
'use strict';
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName = function(){console.log(this.name);};
sayAge = ()=>{console.log(this.age);}
}
let tom = new Animal('tom',19);
let [sayName, sayAge] = [tom.sayName, tom.sayAge];
sayAge(); // 正常输出19
sayName(); // this为undefined
我明白字段函数是属于对象本身而不是原型的,但我不明白为什么箭头函数能绑定this值????
在上面的例子中sayName
会丢失this值我可以理解,但为什么sayAage
不会丢失???
from blog.
'use strict';
let tom = {
name: 'tom',
age: 19,
sayName: function(){console.log(this.name);},
sayAge: ()=>{console.log(this.age);},
};
let [sayName, sayAge] = [tom.sayName, tom.sayAge];
sayAge(); // this指向外面的空对象{},输出undefined
sayName(); // 抛出错误,this为undefined
那为什么这里面的sayAge
就无法绑定对象tom
?
from blog.
@towersxu es6 官方提案目前没有 但在实际应用中 这种写法很常见了 所以一般都会配置对应的 babel plugin
方式二是通过箭头函数来定义方法,如果你写过 React 应用,应该接触过这种方式。
from blog.
提案 已经处于 s3 箭头函数的写法就类似给类定义了 public method fields 是需要配置 transform-class-properties
from blog.
“转换后的 class A 就是一个函数,所以理论上就可以把 A 当作函数调用,但 _classCallCheck 的作用就是禁止将类作为函数调用”。这里应该改成禁止将类当作普通函数调用更合理。毕竟是当作构造函数调用呀。
from blog.
@lz-lee 已纠正
from blog.
我觉得class不仅仅是个语法糖,应该还是加了一些东西的。
class A extends Array {};
var a = new A;
var B = function () {};
B.prototype = Object.create(Array.prototype);
var b = new B;
var c = new Array;
console.log(Array.isArray(a)) //true;
console.log(Array.isArray(b)) //false;
console.log(Array.isArray(c)) //true;
from blog.
厉害
from blog.
箭头函数作用域问题
from blog.
@ChaosGT 箭头函数的this是在定义时就决定的,你的代码中 sayAge
处时 this
执行全局,strict
下就是 undefined
。
你再上面是 class 语法,那里面的定义时, this
为 Animal 的实例。
from blog.
@phyzess 感谢你给出的babel结果,这样就很清楚了,说到底还是解释器硬绑定,和语法本身关系不大,虽然很方便,但个人觉得这破坏了语言的统一性。
「箭头函数不具有自己的 this,它的 this 永远是定义时包裹它的代码块的 this」
这句话的后半句是不对的,箭头函数只有作为class的field时候,才会绑定当前对象,是解释器的trick,其它时候都是从执行的上下文中获取,而不是定义时的代码块。
from blog.
@ChaosGT 用 babel 把上面你写的这段代码编译到 ES5 看一下就能明白了
省略掉无关编译结果,下面这段是你疑惑的解答应该:var Animal = function Animal(name, age) { var _this = this; _classCallCheck(this, Animal); _defineProperty(this, "sayName", function () { console.log(this.name); }); _defineProperty(this, "sayAge", function () { console.log(_this.age); }); this.name = name; this.age = age; };注意两个_defineProperty 的回调函数内对于 this 的使用方式。一个是直接用了 this,一个用了构造实例的闭包,所以一个 this 会丢失(成为undefined),而另一个不会。
结合「箭头函数不具有自己的 this,它的 this 永远是定义时包裹它的代码块的 this」,就可以理解为什么 ES6 编译到 ES5 是这样的实现。其实还是作用域、执行上下文、闭包的问题。
同意。
from blog.
Related Issues (20)
- [译]JavaScript 的时间消耗 HOT 4
- Webpack 4 不完全迁移指北 HOT 23
- 从一道题浅说 JavaScript 的事件循环 HOT 36
- Nginx 上配置 HTTPS 环境 HOT 8
- 列表数据的展示优化 HOT 2
- 处理 undefined 值的7个建议 HOT 1
- How to escape async/await hell HOT 8
- 数制基础 HOT 1
- 浅说 XSS 和 CSRF HOT 18
- 浅说移动前端中 Viewport 和 Viewport units HOT 4
- 浅说虚拟列表的实现原理 HOT 25
- react-tiny-virtual-list的源码解读 HOT 5
- react-virtualized 组件的虚拟列表实现
- react-virtualized 组件的虚拟列表优化分析 HOT 1
- 图片和视频的懒加载 HOT 2
- 从 Hello World 看 RN 的启动流程(一) HOT 2
- 从 Hello World 看 RN 的启动流程(二) HOT 1
- 这样就产生了反射型 XSS 攻击。攻击者可以注入任意的恶意脚本进行攻击,可能注入恶作剧脚本,或者注入能获取用户隐私数据(如cookie)的脚本,这取决于攻击者的目的。
- dom型xss攻击中,我没有理解具体的危害。输入内容是用户自己控制的,即使他输入恶意内容,又能干些什么呢?能用一个具体的案例,讲下攻击者的什么行为给受害者造成了什么危害吗? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.