JavaScript 构造函数和原型

JavaScript 构造函数和原型,第1张

构造函数

JS可以基于构造函数创建实例对象,我们可以用一个简单的函数来举例:

function Person(){
    this.sex = 'male';
    this.Name = 'rober';
    this.Run = function(){console.log(this.Name + 'is running');}
}

let person = new Person();
person.Run() // rober is running

在上文中的Person只是一个函数,里边并没有return 任何东西,但当我们用new 调用构造函数后,便生成了一个person的实例对象。其实JS的new在背后讲要实例化的方法做了一些调整,如下:

function Person() {
    this = {};
    this.sex = 'male';
    this.Name = 'rober';
    this.Run = function() {console.log(this.Name + 'is running');}
    return this;
}

new 关键字自动在函数里讲this初始化,并在最后返回了。这就是为什么我们new一个方法可以有对象可以返回。如果只是“let person = Person()”。那么person便是undefined了。

但Person终究还是一个方法,虽然我们可以让它实例化,但是很容易让人混淆,尤其是用惯JAVA或C#等语言的的人,还是会觉得class更加亲切一点。所以JS也引进了class。但只是为了让用户不会混淆OOP语言的概念,但实质上是一样的。我们就把上边的Person改成class:

class Person{
    sex = 'male'

    constructor(){
        this.name = 'rober';
    }

    Run(){
        console.log(this.name + 'is running');
    }

}


let person = new Person();
person.Run();

当我们用new关键字去实例化class对象时,其实是跟实例化函数是一样的,只不过class 是在constructor方法里去初始化this,并返回。

值得注意的是,class Person的Run方法实例化还是有些特别,跟 function Person 的 Run方法有区别。这就需要了解JS中原型的概念了。

原型 Prototype

原型的概念对于JS来说非常重要,可以说JS是以原型为基础的语言。在JS里,所有的对象都有Prototype属性,这也是JS继承方法的方式。

person.toString();

     当我们调用toString方法时,即使Person并未定义此方法,但JS还是执行并未报错。这是因为JS在Person中未找到toString方法后,便会去其原型里去查找,因为JS所有对象都有原型,所以JS会一层一层的往上找,先是Person的原型,再是Person原型的原型,直到查到Object的原型便到头了,如果还未找到此方法才会报错,toString方法就在Object的原型里,所以并未报错可以正确执行。JS在一层一层的顺着像链一样的原型往上查找,这个链我们称之为原型链。

现在我们回到之前的问题,用class Person 实例化的对象里的方法是存放在原型里,而不是属于自己的方法。

如上图,用class Person 初始化后,Run方法是在原型里的。

 而用function Person 初始化后,Run方法则直接存放在了new 出来的对象里了。

虽然功能是一样的,但是放在原型里就意味着每次初始化新的对象并不需要创建新的Run方法,用Person Class的方法就好,而Person function每次new新的对象都要创建新的Run方法。如果new的对象比较少也不会有什么区别,但想象一下,如果一个大项目,需要new上千个对象,自然用class可以节省更多内存。 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1319780.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-11
下一篇 2022-06-11

发表评论

登录后才能评论

评论列表(0条)

保存