您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页举例说明JavaScript中的实例对象与原型对象

举例说明JavaScript中的实例对象与原型对象

来源:筏尚旅游网
举例说明JavaScript中的实例对象与原型对象

⾸先声明: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()⼀样,前者都是修改⾃⾝,后者是完全改变⾃⾝。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务