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.直接创建对象实例
这恐怕是最简单粗暴的创建对象实例的方式了,JavaScript对于对象实例的理解就是键值对,所以不管是属性,还是方法,都通过键值对的方式声明
不过,这里似乎少了什么东西,对,C类语言中的private,protected,public去哪里了,其实这些东西JavaScript并没有显示的支持,所以通过这种方式创建的对象实例,属性和方法都是public的,如果要实现private之类的,只能借助于闭包或其他方法了
2.通过new方法创建function对象实例
凡是function对象,JavaScript都提供了new方法来创建对象实例(当然,对于基本对象string,number,boolean等,JavaScript和java相似都提供了包装器对象,所以也可以通过new方法来创建,不过并不推荐使用,最好通过字面量方式直接赋值)
这种方法就很像java,php之类的创建对象实例的方式,这种方式就是构造函数方式,不过这里的属性和方法要通过this对象指定才能在外面被引用,var声明的属性或者直接声明的方法都是private的
之所以会出现这种情况,是因为JavaScript作用域以及this对象的关系
3.通过Object对象提供的方法
这种方法既是一个创建对象实例的方法,同时也是一个继承的方法
形式
Object.create(prototype, descriptors)
参数
prototype 必需,要用作原型的对象,可以为 null
descriptors 可选, 包含一个或多个属性描述符的 JavaScript 对象
返回值
一个具有指定的内部原型且包含指定的属性(如果有)的新对象
定义
创建一个具有指定原型且可选择性地包含指定属性的对象
create方法有两个参数,这里暂时忽略descriptors参数,只考虑第一个参数,第一个参数传进去的是对象实例
这里创建了一个新的对象实例y,并且继承了x对象实例的属性和方法
这个方法的实现原理大概如下:
二.使用
1.new方法的使用
4000
之前说过,new方法其实不被推荐使用,其中有一点就是因为这种方法很可能会出错,首先是函数有返回对象实例的时候,new方法创建的就是这个对象实例:
2.一些后记
这里介绍了三种创建对象实例的方式,这三种方式是JavaScript语言本身提供的,实现起来也很简单,我们可以根据自己的需要任意选择
另外,关于继承,之前讲过原型链的继承方式,这里Object提供了一种封装,可以简化我们的一些操作,还有之前说的apply和call方式只是一种应用技巧,也算是“继承”吧,虽然原理上只是浅拷贝
另外还要说明一点就是JavaScript的赋值其实复制的是对象实例的引用,这一点和java很像:
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对象创建及继承原理实例解剖
- JavaScript对象创建及继承原理实例解剖
- javascript的函数、创建对象、封装、属性和方法、继承
- JavaScript 创建对象实例 【每日一段代码77】
- JavaScript的中对象创建和继承原理
- javascript高级程序设计一书----关于创建和对象继承的总结
- javascript的函数、创建对象、封装、属性和方法、继承
- javascript实例教程(5) 利用javascript创建对象
- JavaScript的中对象创建和继承原理
- javascript 面向对象的对象创建与继承
- javascript的自定义实例对象竟然跟C#的创建对象如此相近
- \t\t深入了解javascript的面向对象特性 类和对象的创建 实例化
- javascript 对象基础 继承机制实例【对象冒充】
- javascript的函数、创建对象、封装、属性和方法、继承
- javascript中的对象创建 实例附注释
- javascript 对象基础 继承机制实例 call() apply 方法!
- Javascript创建自定义对象 创建Object实例添加属性和方法
- 在没有类的情况下,JavaScript如何创建对象、实现继承?
- JavaScript面向对象实例——创建日志调试对象来代替alert函数进行调试
- nullJavascript中创建对象的五种方法实例