Javascript 好用的prototype以及各种模式介绍
最初创建对象的时候基本上就是这样子的:
1var people = {
2 name: "Nicholas",
3 age: 29,
4 job: "Software Engineer",
5
6 sayName: function() {
7 console.log(this.name)
8 }
9};
10
后来引入了构造函数模式,差不多就变成了
1function Person(name, age, job) {
2 this.name = name;
3 this.age = age;
4 this.job = job;
5 this.sayName = function() {
6 console.log(this.name);
7 }
8}
9
10var person1 = new Person("Nicholas", 29, "Software Engineer");
11
基本上,这才是我们常见的面向对象模式。
但之后又多了一个原型模式,用prototype
来达到效果,他的优点是可以让所有对象实例共享它所包含的属性和方法。
1function Person() {
2}
3
4Person.prototype.name = "Nicholas";
5Person.prototype.sayName = function() {
6 console.log(this.name);
7};
8var person1 = new Person();
9
当然,之后又出现了更简易的语法。
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
就是修改起来更加方便,而方便起来真的是挺吓人的,这里有个很明确的例子:
1String.prototype.startsWith = function (text) {
2 return this.indexOf(text) == 0;
3}
4
5var msg = "Hello World";
6console.log(msg.startsWith("Hello"));
7
String是原生引用类型的一个(包括Object、Array、String等),都能自定义方法,或者通过typeof Array.prototype.sort
检测方法等,体现出了prototype
的强大。
但是不推荐修改原生对象的原型,以免命名冲突等情况
当然prototype
也有其缺点:
1function Person() {
2}
3
4Person.prototype = {
5 constructor: Person,
6 name: "Nicholas",
7 age: 29,
8 job: "Software Engineer",
9 friends: ["Shelby", "Count"],
10 sayName: function() {
11 console.log(this.name);
12 }
13}
14
15var person1 = new Person();
16var person2 = new Person();
17
18person1.friends.push("Van");
19
20console.log(person1.friends);
21console.log(person2.friends);
22console.log(person1.friends == person2.friends);
23
比如这段,运行结果为:
[ 'Shelby', 'Count', 'Van' ]
[ 'Shelby', 'Count', 'Van' ]
true
换言之,这就是共享的缺点,大家都同样的会变化,因此也不是最优秀的模式,最终定稿的模式是组合使用构造函数模式和原型模式: 前者用于需要定义的实例属性,后者用于需要共享的实例属性,这样极大程度的节省了内存。
修改成这样:
1function Person(name, age, job) {
2 this.name = name;
3 this.age = age;
4 this.job = job;
5 this.friends = ["Shelby", "Court"];
6}
7
8Person.prototype = {
9 constructor: Person,
10 sayName: function() {
11 console.log(this.name);
12 }
13}
14
15var person1 = new Person("Nicholas", 29, "Software Engineer");
16var person2 = new Person("Greg", 27, "Doctor");
17
18person1.friends.push("Van");
19
20console.log(person1.friends);
21console.log(person2.friends);
22console.log(person1.friends == person2.friends);
23
输出为:
[ 'Shelby', 'Court', 'Van' ]
[ 'Shelby', 'Court' ]
false
评论 (0)