Javascript 好用的prototype以及各种模式介绍

最初创建对象的时候基本上就是这样子的:

var people = {
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    
    sayName: function() {
        console.log(this.name)
    }
};

后来引入了构造函数模式,差不多就变成了

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        console.log(this.name);
    }
}

var person1 = new Person("Nicholas", 29, "Software Engineer");

基本上,这才是我们常见的面向对象模式。

但之后又多了一个原型模式,用prototype来达到效果,他的优点是可以让所有对象实例共享它所包含的属性和方法。

function Person() {
}

Person.prototype.name = "Nicholas";
Person.prototype.sayName = function() {
    console.log(this.name);
};
var person1 = new Person();

当然,之后又出现了更简易的语法。

function Person() {
}

Person.prototype = {
    // constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    sayName: function() {
        console.log(this.name);
    }
}

但此时,与上面不同的是,constructor不再指向Person函数,而是指向了Object,我们可以通过注释掉的那句constructor: Person来明确指向,重新指回Person。

感觉上去,使用prototype就是修改起来更加方便,而方便起来真的是挺吓人的,这里有个很明确的例子:

String.prototype.startsWith = function (text) {
    return this.indexOf(text) == 0;
}

var msg = "Hello World";
console.log(msg.startsWith("Hello"));

String是原生引用类型的一个(包括Object、Array、String等),都能自定义方法,或者通过typeof Array.prototype.sort检测方法等,体现出了prototype的强大。
但是不推荐修改原生对象的原型,以免命名冲突等情况

当然prototype也有其缺点:

function Person() {
}

Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    friends: ["Shelby", "Count"],
    sayName: function() {
        console.log(this.name);
    }
}

var person1 = new Person();
var person2 = new Person();

person1.friends.push("Van");

console.log(person1.friends);
console.log(person2.friends);
console.log(person1.friends == person2.friends);

比如这段,运行结果为:

[ 'Shelby', 'Count', 'Van' ]
[ 'Shelby', 'Count', 'Van' ]
true

换言之,这就是共享的缺点,大家都同样的会变化,因此也不是最优秀的模式,最终定稿的模式是组合使用构造函数模式和原型模式:
前者用于需要定义的实例属性,后者用于需要共享的实例属性,这样极大程度的节省了内存。

修改成这样:

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}

Person.prototype = {
    constructor: Person,
    sayName: function() {
        console.log(this.name);
    }
}

var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

person1.friends.push("Van");

console.log(person1.friends);
console.log(person2.friends);
console.log(person1.friends == person2.friends);

输出为:

[ 'Shelby', 'Court', 'Van' ]
[ 'Shelby', 'Court' ]
false

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识, 语法

添加新评论