您的位置:首页 > Web前端 > JavaScript

secrets of the javascript Ninja (Function Prototypes)(javascript忍者的秘密)

2009-03-24 22:01 435 查看
函数原型有很多用途,比如可以用来向一个函数实例上添加一些属性,但是它的一个最主要用途是使JavaScript能够以面向对象的方式编程。

实例化和原型(Instantiation 和 prototypes)

所有函数默认的都会有一个含有空对象的prototype属性,它的这个特性只有在实例化后才会有用,为了能够理解它的这种特性是多么的重要,需要知道一个重要的原则:函数具有双重功能,它可以作为一个平常的函数,也可以作为一个类。

我们可以通过下面一个小例子来看看如何使用prototype属性向一个函数上添加一个功能
function Ninja(){}
Ninja.prototype.swingSword=function(){
return true;
}
var ninja=Ninja();
alert(ninja);//undefined,说明不是Ninja的一个实例
var ninja2=new Ninja();
alert(ninja2.swingSword);//true
从上面的这个例子,我们可以发现以下两个问题:
1.为了产生一个函数的实例对象必须使用new操作符调用该函数。

2.swingSword变成了Ninja的实例ninja2的一个属性。

对于函数Ninja来说,由于使用new操作符调用它,我们也可以认为他是一个构造函数。这就意味着,它使用new操作符调用函数的时候,该函数中this所指向的上下文就是对象自身的实例(即和prototype相同),这段话不是太好理解,来让我们看一个例子:

function Ninja(){
this.swung = false;
// Should return true
this.swingSword = function(){
return !this.swung;
};
}
// Should return false, but will be overridden
Ninja.prototype.swingSword = function(){
return this.swung;
};
var ninja = new Ninja();
alert(ninja.swingSword());


从上面的例子我们可以发现实例对象调用它的同名方法的顺序:

1.绑定在prototype上的属性。

2.绑定在构造函数内的属性。

另外一个需要了解的是绑定在prototype上的属性,他可以被更新和改变,即使一个对象被实例化后:如下

function Ninja(){
this.swung = true;
}
var ninja = new Ninja();
Ninja.prototype.swingSword = function(){
return this.swung;
};
alert(ninja.swingSword());


对象类型

还是以例子说话:

function Ninja(){}
var ninja = new Ninja();
alert(typeof ninja);
alert(ninja instanceof Ninja);
alert(ninja.constructor == Ninja);


从上面的例子中,我们可以看到:

1.所有的示例对象如果使用typeof检测都是object类型

2.instanceof 实例对象是由那个函数生成的。

3.任何实例都有个constructor属性,用来引用生成该实例对象的构造函数。

为了证明第三个观点,下面来看一个简单的例子:

var ninja = new Ninja();
var ninja2 = new ninja.constructor();
alert(ninja2 instanceof Ninja);//true


继承与prototype链

在这里我们还可以看到instanceof的一个重要特性:

function Person(){}
Person.prototype.dance = function(){};
function Ninja(){}
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
// Only this maintains the prototype chain
Ninja.prototype = new Person();
var ninja = new Ninja();
alert(ninja instanceof Ninja);//true
alert(ninja instanceof Person);//true
alert(ninja instanceof Object);//true


有很多方法从函数的prototype属性上复制功能(方法和函数),但是只有一种情况能够形成prototype链。即:SubFunction.prototype = new SuperFunction();.

HTML prototypes

在Internet Explorer 8, Firefox, Safari, 和 Opera这些浏览器中这些可以使用prototype扩展dom元素:
来看看一个简短的例子:

<div id="a">I'm going to be removed.</div>
<div id="b">Me too!</div>
HTMLElement.prototype.remove = function(){
if ( this.parentNode )
this.parentNode.removeChild( this );
};
// Old way
var a = document.getElementById("a");
a.parentNode.removeChild( a );
// New way
document.getElementById("b").remove();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: