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

JavaScript之对象实例的创建和继承

2015-02-11 21:59 543 查看
之前着重说过JavaScript的原型链继承方式,以及通过apply或者call函数实现“继承”的方式,不过,要彻底理解继承,需要弄清楚JavaScript的对象实例是如何创建的

Douglas Crockford说过:JavaScript除了underfined和null,其他都是对象,其实用typeof测了一下,发现null也是对象(据说这是JavaScript语言设计的错误)

另外,Object对象是根对象,其余的function,number,string以及array等,都是通过原型链的方式继承于object对象,所以,几乎一切皆对象

但程序中我们不会关心对象的创立过程,而会关心对象实例的创建过程

一. 定义

1.直接创建对象实例

var x = {
value : "Hi!",
print : function() {
console.log(this.value);
}
}
console.log(x.value); //Hi!
x.print(); //Hi!


这恐怕是最简单粗暴的创建对象实例的方式了,JavaScript对于对象实例的理解就是键值对,所以不管是属性,还是方法,都通过键值对的方式声明
不过,这里似乎少了什么东西,对,C类语言中的private,protected,public去哪里了,其实这些东西JavaScript并没有显示的支持,所以通过这种方式创建的对象实例,属性和方法都是public的,如果要实现private之类的,只能借助于闭包或其他方法了

2.通过new方法创建function对象实例

凡是function对象,JavaScript都提供了new方法来创建对象实例(当然,对于基本对象string,number,boolean等,JavaScript和java相似都提供了包装器对象,所以也可以通过new方法来创建,不过并不推荐使用,最好通过字面量方式直接赋值)

var x = new String("Hi!");
var y = "Hi!";   //推荐使用


var x = function() {
this.value = "Hi!";
this.print = function() {
console.log(this.value);
}
}
console.log((new x()).value); //Hi!
(new x()).print(); //Hi!


这种方法就很像java,php之类的创建对象实例的方式,这种方式就是构造函数方式,不过这里的属性和方法要通过this对象指定才能在外面被引用,var声明的属性或者直接声明的方法都是private的

var x = function() {
var value = "Hi!";
function print() {
console.log(this.value);
}
}
console.log((new x()).value); //underfined
(new x()).print(); //报错

之所以会出现这种情况,是因为JavaScript作用域以及this对象的关系

3.通过Object对象提供的方法

这种方法既是一个创建对象实例的方法,同时也是一个继承的方法

形式

Object.create(prototype, descriptors)

参数

prototype 必需,要用作原型的对象,可以为 null

descriptors 可选, 包含一个或多个属性描述符的 JavaScript 对象

返回值

一个具有指定的内部原型且包含指定的属性(如果有)的新对象

定义

创建一个具有指定原型且可选择性地包含指定属性的对象

create方法有两个参数,这里暂时忽略descriptors参数,只考虑第一个参数,第一个参数传进去的是对象实例

var x = {
value : "Hi!",
print : function() {
console.log(this.value);
}
}
var y = Object.create(x);
console.log(y.value); //Hi!
y.print(); //Hi!

这里创建了一个新的对象实例y,并且继承了x对象实例的属性和方法

这个方法的实现原理大概如下:
Object.create = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
所以还是原型链的继承方式,只是封装了一层而已,让我们的操作更加简化了

二.使用

1.new方法的使用

4000
之前说过,new方法其实不被推荐使用,其中有一点就是因为这种方法很可能会出错,首先是函数有返回对象实例的时候,new方法创建的就是这个对象实例:

var x = function() {
this.num = 3;
return {
value : "Hi!"
}
}
console.log((new x()).num); //underfined
console.log((new x()).value); //Hi!
不过当函数返回基本对象(number,string)的时候,new方法却不受返回值的影响(tips:这里不考虑包装器对象,其实如果返回包装器对象new方法要受影响)

var x = function() {
this.num = 3;
return "Hi!";
}
console.log((new x()).num); //3
因此使用new方法时是要格外注意是否该函数有返回对象实例

2.一些后记
这里介绍了三种创建对象实例的方式,这三种方式是JavaScript语言本身提供的,实现起来也很简单,我们可以根据自己的需要任意选择

另外,关于继承,之前讲过原型链的继承方式,这里Object提供了一种封装,可以简化我们的一些操作,还有之前说的apply和call方式只是一种应用技巧,也算是“继承”吧,虽然原理上只是浅拷贝

另外还要说明一点就是JavaScript的赋值其实复制的是对象实例的引用,这一点和java很像:

var x = {
value : "Hi"
}
var y = x;
y.value = "Hello!";
console.log(x.value); //Hello!
这一点一定要注意(不过java的基本类型是不会复制引用的,JavaScript也是如此,number和string赋值不会复制引用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 继承 对象