资讯专栏INFORMATION COLUMN

ES5的原型链和ES6的类实现详解

Warren / 1523人阅读

摘要:类才支持实例属性代码解读上面暂时只是概念性的写法,事实上,的类只是一个原型链的语法糖而已,主要是从写法上更接近于面相对象的类而已,另外一个作用就是区分的构造函数和函数之间的区分。

ES5的原型链和ES6的类实现详解

JavaScript最初设计时受到了面相对象编程的影响,从而引入了new关键字,来实例化对象。而在ES5中new后面跟着的是构造函数(也是函数),而到了ES6则改成了clas了,而一开始new创建对象都是独立的对象,并不能像java那样拥有继承的概念,去共享变量和方法,为了解决这个问题,JavaScript就又给构造函数设计了一个prototype属性,这样所有私有的方法和变量就放到构造函数里面定义,而所有的公共的变量和方法就放到prototype对象里面,这样当构造函数创建一个实例化的对象的时候,就即拥有自己的私有变量和方法,也有公有的变量和方法了,实例化出来的对象的私有方法和变量修改都不会互相有影响,只有在修改公有的变量和方法的时候是对所有实例生效的。

ES5原型链

Example

function Person(name){
    this.name = name;
}
(function ($Person){
    $Person.prototype = {
        welcome: "hello",
        introduce: function(){
            return this.welcome + ",I am " + this.name;
        }
    }
})(Person)

var person1 = new Person("arvin");
var person2 = new Person("peter");
console.log(person1.introduce());   // hello,I am arvin
console.log(person2.introduce());   // hello,I am peter

person1.__proto__.welcome = "hi";
console.log(person1.introduce());   // hi,I am arvin
console.log(person2.introduce());   // hi,I am peter

代码解读:以上是本人推荐在使用ES5时,写原型链的方法,目的是为了代码简洁,方便复用,仅供参考。代码中在原型链上定义了一个welcome公共变量,这里要注意的是如果有同样名称的私有变量welcome时,原型方法introduce里面的this.welcome会首先查找私有变量welcome并使用,这个其实就和面相对象的覆写类似了。另外可以看出,ES5的构造函数(一般首字母大写以区分普通函数)在new的时候确实是创建了不同的区块来存放其私有变量name的值的,而对于原型链的变量welcome和方法introduce也确实是各个Person实例共用了同一块内存区域的,只要其中一个修改了原型链上的变量其他所有的对象实例再调用的时候从公共内存取出来的也就是被修改过只有的值了,这里要注意的是,构造函数new出来的实例对象,创建出来的指向原型链prototype的是其__proto__属性,也就是说person1.__proto__ === Person.prototype === person2.__proto__,这也从实际上证明了原型链对象在内存中只存了一份,是共用的

ES6类

Example

class Person {
    constructor(name) {
        this.name = name;
    }
    welcome = "hello";  // S7才支持实例属性
    introduce(){
        return this.welcome + ",I am " + this.name;
    }
}

var person1 = new Person("arvin");
var person2 = new Person("peter");
console.log(person1.introduce());   // hello,I am arvin
console.log(person2.introduce());   // hello,I am peter

person1.__proto__.welcome = "hi";
console.log(person1.introduce());   // hi,I am arvin
console.log(person2.introduce());   // hi,I am peter

代码解读:上面暂时只是概念性的写法,事实上,ES6的类只是一个ES5原型链的语法糖而已,主要是从写法上更接近于面相对象的类而已,另外一个作用就是区分ES5的构造函数和函数之间的区分。

小结:对于ES5和ES6的类似面相对象和非面向对象的原因,以java为例提出以下几点个人见解:

1、java在继承(extend)的时候,子类是会复制一遍所有父类的方法和属性(除已覆写的除外)到一个独立的内存空间中的,即所有子类之间不存在任何的关系;而这点其实就和ES5的原型继承prototype和ES6的extend有很大的不同了。

2、java在new创建一个实例的时候同样是会开辟一个独立的属于该实例的内存空间,同一个类的实例之间互不影响;而ES5和ES6的创建实例的时候实例仍然是和类是存在关联的,而且是可以直接影响到类以及其他子类的公共状态和方法的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84160.html

相关文章

  • ES5原型链和ES6实现详解

    摘要:类才支持实例属性代码解读上面暂时只是概念性的写法,事实上,的类只是一个原型链的语法糖而已,主要是从写法上更接近于面相对象的类而已,另外一个作用就是区分的构造函数和函数之间的区分。 ES5的原型链和ES6的类实现详解 JavaScript最初设计时受到了面相对象编程的影响,从而引入了new关键字,来实例化对象。而在ES5中new后面跟着的是构造函数(也是函数),而到了ES6则改成了cla...

    王伟廷 评论0 收藏0
  • 详解javascript

    摘要:原文地址详解的类博主博客地址的个人博客从当初的一个弹窗语言,一步步发展成为现在前后端通吃的庞然大物。那么,的类又该怎么定义呢在面向对象编程中,类是对象的模板,定义了同一组对象又称实例共有的属性和方法。这个等同于的属性现已弃用。。 前言 生活有度,人生添寿。 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客   Javascript从当初的一个弹窗语言,一...

    hufeng 评论0 收藏0
  • 详解javascript

    摘要:原文地址详解的类博主博客地址的个人博客从当初的一个弹窗语言,一步步发展成为现在前后端通吃的庞然大物。那么,的类又该怎么定义呢在面向对象编程中,类是对象的模板,定义了同一组对象又称实例共有的属性和方法。这个等同于的属性现已弃用。。 前言 生活有度,人生添寿。 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客   Javascript从当初的一个弹窗语言,一...

    marek 评论0 收藏0
  • 剖析JS原型链和继承

    摘要:接下来我们来聊一下的原型链继承和类。组合继承为了复用方法,我们使用组合继承的方式,即利用构造函数继承属性,利用原型链继承方法,融合它们的优点,避免缺陷,成为中最常用的继承。 JavaScript是一门面向对象的设计语言,在JS里除了null和undefined,其余一切皆为对象。其中Array/Function/Date/RegExp是Object对象的特殊实例实现,Boolean/N...

    darkerXi 评论0 收藏0

发表评论

0条评论

Warren

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<