举例说明JavaScript中的实例对象与原型对象
作者:bea
首先声明:javascript中每个对象都有一个constructor属性和一个prototype属性。constructor指向对象的构造函数,prototype指向使用构造函数创建的对象实例的原型对象。 function Person(){ } var person = new Person(); Person.prototype = { constructor : Person, name : 'zxs', age : 24, sayName : f
首先声明:javascript中每个对象都有一个constructor属性和一个prototype属性。constructor指向对象的构造函数,prototype指向使用构造函数创建的对象实例的原型对象。
function Person(){
}
var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName();
在这段代码中会报错,sayName() is not defined。根据javascript高级程序设计第二版的解释,是因为重写的原型切断了构造函数与最初原型之间的联系。但是我们调整一下上面语句的顺序。如下:
function Person(){
}
//var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
alert(person.constructor) //function Object() { [native code]} or function Person() {} 取决与蓝色的语句是否有效
注意上面两段代码等号中间的语句。按第二段的顺序写代码,将会输出 ”zxs“,这个结果说明在第一种情况下报错并不能说明是因为切断了构造函数与原想之间的联系引起的。
Person.prototype = {}
本来就是一种定义对象的方法,而且在javascript中每个对象的constructor属性都默认的指向Object构造函数,这也就不难说明重写原型对象确实切断了构造函数与最初原型之间的联系,但并不能说明这种联系被切断之后 person就不能访问到sayName()函数。
现在有这样的假设:函数的prototype属性所指向的原型对象,与我们显示新建的原型对象并不是完全等同的。当我们调用函数的时候会创建一个原型对象,此时会首先查找当前环境中是否存在其原型对象,如果程序中不存在,就创建一个,如果环境中存在,侧查找他们的属性和方法,最后根据查找的结果返回一个原型对象,这个对象中的属性和方法总是优先使用默认原型中的属性和方法,也就是构造函数中定义的属性和方法。当当调用的方法或属性不存在于默认的原型中时,才使用定义在Person.prototype = {} 的属性和方法。
javascript是解释性的语言,语句都是顺序执行的,在第一段代码中,当我们使用 new 关键字创建新对象的时候,Person.prototype = {} 并没有执行,也就是说在当前的执行环境中找不到其中定义的方法和属性,而构造函数中没有该方法,所以出错。就像一个变量,给他赋值的时候程序没有执行将不能使用。在第二段中环境中已经存在该调用的方法,构造函数的原型对象已经创建完毕,所以可以得到结果。
再看下面的一段程序:
//////////////////////////////////////////////////////////////////////////
function Person(){}
/*===========================================================*/
var person = new Person();
Person.prototype.name = 'song';
/*===========================================================*/
//Person.prototype.sayName = function(){alert(this.name)};
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName(); // error
//////////////////////////////////////////////////////////////////////////
function Person(){ }
/*var person = new Person();*/
Person.prototype.name = 'song';
/*Person.prototype.sayName = function(){alert(this.name)};*/
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
从这里可以看出使用 Person.prototype.name = '',的方式不论在什么地方创建对象都能被访问,如果同时存在对象字面量和这种方法定义原型对象,将使用后定义的作为最终值。并且对原型对象使用对象字面量定义之后,该定义必须出现在创建对象的语句之前才能被访问到。
实例不能访问到原型对象中的属性和方法,不仅仅是因为重写原型对象切断了构造函数与最初原型之间的联系。
function Person(){
}
var person = new Person();
Person.prototype = {
//constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName();
以上代码在实例化对象时构造函数的原型为空,它没有任何除默认属性以外的属性。重写构造函数的原型确实切断了构造函数与最初原型之间的联系。
在使用 new 操作符以后构造函数的原型对象中的属性和方法已经添加到 person对象中。因为以上方法为函数原型添加新属性和方法不具有动态性,所以person不能访问到新添加的属性和方法。
重写原型对象之后,就如同如下代码:
var o = {
name : 'zxs'
}
var obj = o;
o = {}
console.log(o.name);
此时输出的值是undefined,因为,对象是一个引用类型,“=”是赋值操作符,并且其运算顺序是从右往左。o={}就是说o的指向已经改变,是一个空对象。 Person.prototype.mothed = function() {}与Person.prototype={mothed:function(){}}的区别就如同 arr = []和arr.push()一样,前者都是修改自身,后者是完全改变自身。
有用 | 无用
function Person(){
}
var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName();
在这段代码中会报错,sayName() is not defined。根据javascript高级程序设计第二版的解释,是因为重写的原型切断了构造函数与最初原型之间的联系。但是我们调整一下上面语句的顺序。如下:
function Person(){
}
//var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
alert(person.constructor) //function Object() { [native code]} or function Person() {} 取决与蓝色的语句是否有效
注意上面两段代码等号中间的语句。按第二段的顺序写代码,将会输出 ”zxs“,这个结果说明在第一种情况下报错并不能说明是因为切断了构造函数与原想之间的联系引起的。
Person.prototype = {}
本来就是一种定义对象的方法,而且在javascript中每个对象的constructor属性都默认的指向Object构造函数,这也就不难说明重写原型对象确实切断了构造函数与最初原型之间的联系,但并不能说明这种联系被切断之后 person就不能访问到sayName()函数。
现在有这样的假设:函数的prototype属性所指向的原型对象,与我们显示新建的原型对象并不是完全等同的。当我们调用函数的时候会创建一个原型对象,此时会首先查找当前环境中是否存在其原型对象,如果程序中不存在,就创建一个,如果环境中存在,侧查找他们的属性和方法,最后根据查找的结果返回一个原型对象,这个对象中的属性和方法总是优先使用默认原型中的属性和方法,也就是构造函数中定义的属性和方法。当当调用的方法或属性不存在于默认的原型中时,才使用定义在Person.prototype = {} 的属性和方法。
javascript是解释性的语言,语句都是顺序执行的,在第一段代码中,当我们使用 new 关键字创建新对象的时候,Person.prototype = {} 并没有执行,也就是说在当前的执行环境中找不到其中定义的方法和属性,而构造函数中没有该方法,所以出错。就像一个变量,给他赋值的时候程序没有执行将不能使用。在第二段中环境中已经存在该调用的方法,构造函数的原型对象已经创建完毕,所以可以得到结果。
再看下面的一段程序:
//////////////////////////////////////////////////////////////////////////
function Person(){}
/*===========================================================*/
var person = new Person();
Person.prototype.name = 'song';
/*===========================================================*/
//Person.prototype.sayName = function(){alert(this.name)};
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName(); // error
//////////////////////////////////////////////////////////////////////////
function Person(){ }
/*var person = new Person();*/
Person.prototype.name = 'song';
/*Person.prototype.sayName = function(){alert(this.name)};*/
Person.prototype = {
constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
从这里可以看出使用 Person.prototype.name = '',的方式不论在什么地方创建对象都能被访问,如果同时存在对象字面量和这种方法定义原型对象,将使用后定义的作为最终值。并且对原型对象使用对象字面量定义之后,该定义必须出现在创建对象的语句之前才能被访问到。
实例不能访问到原型对象中的属性和方法,不仅仅是因为重写原型对象切断了构造函数与最初原型之间的联系。
function Person(){
}
var person = new Person();
Person.prototype = {
//constructor : Person,
name : 'zxs',
age : 24,
sayName : function(){alert(this.name)}
}
person.sayName();
以上代码在实例化对象时构造函数的原型为空,它没有任何除默认属性以外的属性。重写构造函数的原型确实切断了构造函数与最初原型之间的联系。
在使用 new 操作符以后构造函数的原型对象中的属性和方法已经添加到 person对象中。因为以上方法为函数原型添加新属性和方法不具有动态性,所以person不能访问到新添加的属性和方法。
重写原型对象之后,就如同如下代码:
var o = {
name : 'zxs'
}
var obj = o;
o = {}
console.log(o.name);
此时输出的值是undefined,因为,对象是一个引用类型,“=”是赋值操作符,并且其运算顺序是从右往左。o={}就是说o的指向已经改变,是一个空对象。 Person.prototype.mothed = function() {}与Person.prototype={mothed:function(){}}的区别就如同 arr = []和arr.push()一样,前者都是修改自身,后者是完全改变自身。
有用 | 无用
猜你喜欢
您可能感兴趣的文章:
- 使用javascript插入样式
- jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
- javascript实现数组去重的多种方法
- javascript实现PC网页里的拖拽效果
- Jquery实现简单的轮播效果(代码管用)
- node模块机制与异步处理详解
- JS中创建函数的三种方式及区别
- 使用jQuery操作HTML的table表格的实例解析
- Javascript数组Array方法解读
- GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
- Javascript数组Array基础介绍
- 深入探究JavaScript中for循环的效率问题及相关优化
- 简单谈谈json跨域
- 详解JavaScript中数组和字符串的lastIndexOf()方法使用
- Node.js编写爬虫的基本思路及抓取百度图片的实例分享
- JavaScript中循环遍历Array与Map的方法小结
- Node.js的Express框架使用上手指南
- Node.js项目中调用JavaScript的EJS模板库的方法
- JavaScript操作HTML DOM节点的基础教程