JS之prototype基础篇

本文介绍了JavaScript中的原型(prototype)概念,包括如何通过prototype为已定义的类添加属性和方法,探讨了prototype链的工作原理,以及如何正确使用构造函数和prototype进行类的继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript语言是一个动态语言,其动态性之一就体现在可以通过prototype来为已经定义好的的"类"添加属性和方法。这里来了解一下prototype的基础知识。prototype是"构造函数"的属性,不是实例的属性.

function HiClass() {
	this.sayHi = function(){
		alert("hi");
	}
}

var obj = new HiClass(); 
alert(HiClass.prototype);//outputs [object, object]
alert(obj.prototype);//outputs undefined
在用prototype的方式实现继承一个类的时候,要注意其可能覆盖别的prototype方式添加的属性和方法。如果是HiClass.prototype.prop = 'value';
在HiClass.prototype = new HelloClass();之前,执行HiClass.prototype = new HelloClass();之后,HiClass的实例中不会有prop属性,这个应该很好理解。但是要注意代码中不要不小心存在这样的bug。

function HiClass() {
	this.sayHi = function(){
		alert("hi");
	}
}


function HelloClass() {
	this.sayHello = function(){
		alert("hello");
	}	
}
//HiClass.prototype.prop = 'value';
HiClass.prototype = new HelloClass();
HiClass.prototype.prop = 'value';

var obj = new HiClass();
obj.sayHello();
alert(obj.prop);
在JavaScript中有一个prototype链,在对一个对象实例上调用方法或者获取属性的时候,先看实例对应的类有没有对应的定义,没有的话会沿着prototype链一直找,找不到则为undefined。
function Object2() {
    this.sayHi = function(){
        alert("hi Object2");
    }
}

function Object3() {
    this.sayHi = function(){
        alert("hi Object3");
    }
    
    this.sayHello = function(){
        alert("hello Object3");
    }
    
}

Object2.prototype = new Object3();

var obj = new Object2();
obj.sayHi();
obj.sayHello();

Object.prototype.foo = function(){
    alert("f00 Object");
};
obj.foo();
调用obj.sayHi();的时候,sayHi在Object2里已经定义,则调用本身的定义。

调用obj.sayHello();的时候,sayHello在Object2里没有定义,但是由于prototype指向了Object3,则从Object3找,找到了执行。

调用obj.foo();的时候,sayHello在Object2和Object3里没有定义,但是由于JS中所有实例都会继承Object,所以可以在Object的prototype找到foo,然后执行。

如果在实例里添加的属性和方法与prototype里的属性和方法重名,相对于实例和prototype都有这个属性和方法,只是由于prototype链的访问顺序,先访问到实例中的属性和方法。如下面的例子说明了这一点:

function Test(){};

Test.prototype.prop1 = 'prop value';

var obj = new Test();

obj.prop1 = 'instance value';

alert(obj.prop1 );//outputs instance value

alert(obj.hasOwnProperty("prop1"));//outputs true

delete obj.prop1;alert(obj.prop1 ); //outputs prop value
alert(obj.hasOwnProperty("prop1"));//outputs false
alert("prop1" in obj);//outputs true

delete Test.prototype.prop1;alert(obj.prop1 );//outputs undefined
再来看看一些构造函数和prototype的使用:

var myObj = {
	prop1:'value1',
	prop2:'value2'
}

Object.prototype.foo = function(){
	alert("f00 Object");
};

//等价于
//var myObj = new Object();
//myObj.prop1 = 'value1';
//myObj.prop2 = 'value2';

alert(myObj.prop2);
myObj.foo();
同时也可以如下的方式对prototype赋值

function TestCls(){
	
}
TestCls.prototype = {
	prop1:'value1',
	prop2:'value2'
};
myObj = new TestCls();
alert(myObj.prop2);
上面的做法中有一个问题是改变prototype后,constructor也改变了。
所以要将prototype.constructor之前的值,比如第一个例子中要加上 HiClass.prototype.constructor=HiClass
上面的做法中有一个问题是改变prototype后,constructor也改变了。
所以要将prototype.constructor之前的值,比如第一个例子中要加上 HiClass.prototype.constructor=HiClass
function HiClass() {
	this.sayHi = function(){
		alert("hi");
	}
}


function HelloClass() {
	this.sayHello = function(){
		alert("hello");
	}	
}

HiClass.prototype = new HelloClass();
HiClass.prototype.constructor=HiClass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值