摘要:和大多数浏览器的实现中,每一个对象都有属性除外,指向对应的构造函数的属性。作为构造函数的语法糖,同时有属性和属性,因为存在两条继承链。
前言
es6的class其实是构造函数的语法糖,但是又有区别,下面来详细分析下class
定义先来看下class的定义的代码
class Point{ constructor(){} toString(){} } var p = new Point() p.constructor === Point.prototype.contructor//true Object.keys(Point.prototype)//[] Object.getOwnPropertyNames(Point.prototype)//["constructor","toString"]区别
在类的实例上调用方法,就是调用类的原型上的方法,但是类内部的方法是不可枚举的,构造函数的方法是可枚举的(是否可被for...in遍历,object.keys),构造函数可以遍历除contructor之外的方法
constructor是类默认的方法,通过new生成实例时自动调用该方法,如果没有被显示定义,这个方法会被自动创建。
类只能通过new生成实例对象,如果像直接调用class会报错。
类的所有实例共享一个原型对象
p2.__proto__ === p1.__proto__;//true
这也就意味着可以通过实例的__proto__属性为class添加方法,不推荐使用,因为会影响到其他实例
class不存在变量提升,这个和继承有关,必须保证子类在父类之后定义
类和模块内部默认都是使用严格模式
class可以自定义原生数据结构(Array,String等)的子类,这是es5无法做到的,因为es5是先新建子类的this,再将父类的属性添加到子类上,由于父类的内部属性子类无法获取,导致无法继承原生的构造函数
继承子类必须在constructor中调用super方法,否则新建实例会报错,因为子类没有自己的this,而是继承了父类的this,这和es5中的继承不一样,
因为es5中的继承是先创造子类的实例对象this,再将父类的方法添加到this上(parent.call(this)),es6中是先继承父类的实例对象this,然后再用子类的构造函数修改this。如果子类没有定义constructor,那么这个方法会被默认添加。
在子类的构造函数中,只有调用super关键字之后,才可使用this关键字,否则会报错,因为子类实例的构建基于对父类实例的加工,只有super方法才能返回父类的实例。
prototype和__proto__
大多数浏览器的es5实现中,每一个对象都有__proto__属性(IE8除外),指向对应的构造函数的prototype属性。class作为构造函数的语法糖,同时有prototype属性和__proto__属性,因为存在两条继承链。
子类的__proto__属性表示构造函数的继承,总是指向父类
子类prototype属性的__proto__属性表示方法的继承,总是指向父类的prototype属性
class的静态方法如果在一个方法前加上static关键字,就表示该方法不会被实例继承,而是直接通过类调用,成为‘静态方法’。
看下代码
class Foo{ static classMethod(){} } Foo.classMethod(); class Bar extends Foo(){ static classMethod(){ return super.classMethod() } } Bar.classMethod();
上面Foo类有静态方法classMethod,只能通过Foo.classMethod调用,不可通过实例调用,否则会报错,父类的静态方法可被子类继承。
class的静态属性静态属性是指class本身的属性,即class.propname,而不是定义在实例对象(this)上的属性。
class Foo{} Foo.prop = 1; Foo.prop //1
上面的方法可以读、写Foo类的静态属性prop,但是es6中规定,class中只有静态方法,没有静态属性
new.target属性es6为new命令引入了new.target属性,返回new命令所作用的构造函数,如果构造函数不是通过new命令调用的,那么new.target会返回undefined,因此这个属性可以判断构造函数是如何被调用的
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97352.html
摘要:中的同名的实际上就是我们在的原型继承中使用的构造函数,所以中的是对中的构造函数的一种包装。我们发现,在中设定的属性被放在的构造函数中,而方法则以键值对的形式传入一个函数中。大家是不是对这种继承模式似曾相识呢对了,这就是所谓的构造函数窃取。 ES6中增加了一些新特性,但从底层的角度来说,只是一些语法糖。但是就我个人来说,如果不了解这些语法糖的本质,是用不安心的。那我们要如何揭开这些语法糖...
摘要:一用定义一个空类在中在中结论这个结果很清晰,原来中的类在中也是定义一个构造函数,然后返回出来。 这篇文章用代码对比的方式解释ES6中的类如果用我们熟悉的ES5来看是什么样的。 一、用class定义一个空类在ES6中: class Person { } 在ES5中: var Person = (function () { function Person() { } ...
摘要:请看对应版本干了什么可知,相当于以前在构造函数里的行为。这种写法会与上文中写法有何区别我们在环境下运行一下,看看这两种构造函数的有何区别打印结果打印结果结合上文中关于原型的论述,仔细品味这两者的差别,最好手动尝试一下。 ES6 class 在ES6版本之前,JavaScript语言并没有传统面向对象语言的class写法,ES6发布之后,Babel迅速跟进,广大开发者也很快喜欢上ES6带...
摘要:不同于其他面向对象语言,以前的中中没有类的概念,主要是通过原型的方式来实现继承,中引入了原型链,并且将原型链用来实现继承,其核心是利用原型使得一个对象继承另一个对象的方法和属性,中原型继承的关键是将一个实例的原型对象指向另一个实例,因此前一 不同于其他面向对象语言,ES6以前的JavaScript中中没有class类的概念,主要是通过原型的方式来实现继承,JavaScript中引入了原...
摘要:前言见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正。倘若用的是中文搜索。所以最终的实例对象仍然能进行正常的原型链回溯,回溯到原本的所有原型方法这样通过一个巧妙的欺骗技巧,就实现了完美的继承。 前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正。 20180201更新: 修改用词描述,如组合寄生式改成寄生组合式,修改多处笔误(感谢@Yao Ding的...
阅读 5271·2021-09-22 15:59
阅读 1857·2021-08-23 09:42
阅读 2563·2019-08-29 18:42
阅读 3446·2019-08-29 10:55
阅读 2060·2019-08-27 10:57
阅读 1761·2019-08-26 18:27
阅读 2722·2019-08-23 18:26
阅读 2913·2019-08-23 14:40