JavaScript prototype

原型是什么

在 JavaScript 中,prototype 是函数的一个属性,每个函数中都有一个prototype属性,函数的原型为对象。它主要在函数用作构造函数时使用。

1
2
3
function Person(){
}
console.log(Person.prototype);//Object

由于prototype属性包含的是一个对象,所有我们可以这样为原型上添加属性方法

1
2
3
4
5
6
function Person(){
}
Person.prototype.name = "zhou";
Person.prototype.sayName = function(){
console.log(this.name);
}

也可以这样

1
2
3
4
5
6
7
8
function Person(){
}
Person.prototype = {
name : "zhou",
sayName : function(){
console.log(this.name);
}
}

当我们创建一个对象时

1
2
var a = new Person();
a.sayName();//zhou

为什么a对象能调用Person.prototype中的属性呢,JavaScript给对象提供了一个名为__proto__的隐藏属性,

这个对象会默认指向它构造函数的原型对象。上边的那个栗子a.__proto__ 就指向了Person.prototype

a.__proto__ === Person.prototype//true

虽然对象有 __proto__ 属性,

但是千万别直接访问 __proto__ 属性,因为有些浏览器并不支持直接访问它。

我们再来看看执行这段代码是引擎做了哪些事情。

  1. 首先,尝试遍历a对象中的所有方法,发现没有sayName方法。
  2. 查找sayName方法的请求被委托给了对象a的构造函数的原型,通过对象的__proto__指向了构造函数的原型Person.prototype。发现有这个方法。

在看一个”类”继承另一个类的栗子

1
2
3
4
5
6
7
8
9
10
11
12
13

function A(){

}
A.prototype.name = "zhou";

function B(){

}
B.prototype = new A();

var b = new B();
console.log(b.name); //zhou

再来看看执行这段代码是引擎做了哪些事情。

  1. 尝试遍历对象b中的属性,发现没有找到name这个属性
  2. 查找name属性的请求被委托给了对象b的构造函数的原型,它被b.__proto__指向了B.prototype,而B.prototype又被设置成了通过new A() new出来的一个对象。
  3. 在该对象中没有找到name属性。于是请求继续被委托给了这个这个对象构造函数的原型A.prototype
    4 在A.prototype 找到name属性,并返回

prototype 的典型示例

当我们用jQuery时,trim这个方法用来去空格很爽有木有。

我们可以自己给String添加一个这样的方法

1
2
3
4
5
6
7
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/(^\s+)|(\s+$)/g,"");
}
}

console.log((" qw ").trim());//qw

有错误的地方欢迎拍砖