【javascript笔记】关于函数的构造函数和prototype<四>
2014-11-08 14:40
483 查看
一,构造函数创建对象
到此为止 咱们做一个实验:alert(person1.sayName==person2.sayName) //输出为false.
不是同一个函数对象这似乎很许多强类型语言 比如java和c#类似 声明类的属性 然后设置getset方法去调用
但是 为每一个对象都去初始化这样 “执行同一个动作”的函数对象 是否合乎情理呢,这样我们就自然而然想到了j
ava中的静态关键字,
我们姑且可以将prototype理解为静态的成员或者方法,new的对象是共享的,这样我们就会节约内存?
二,再来看原型模式创建对象
这时候大家就会奇怪,不是说原型里面都是共享的吗?为什么person2输出的还是原型设置的nicolas 而不是Jack;请注意:这里我们为person1的name设置了新的值后; "如果我们在实例中添加了一个属性,并且该属性与实例原型中的一个实例重名 ,那我们就是在实例中创建了该属性,换句话说就是:person1.name='Jack';这一句代码表示了这个name是属于实例的属性.它会阻止我们去访问实例的原型中的nicolas";当然我们也可以通过代码delete
person1.name; 去删除person1.name这个实例属性,执行了这局代码后:
alert(person1.name);//nicolas 原型属性
javascript里面有很多判断属性是属于实例或者原型的,请大家自行搜索。
三,更加简单的原型语法:以字面量形式创建原型对象
五,原型存在的问题
最重要的问题就是 共享的属性若是引用类型,只要任何实例一改动,原型里面的内容也会改动;
六,组合使用构造函数和原型模式
结束~
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; this.getName=function(){ return this.name; } this.getAge=function(){ return this.age } this.getJob=function(){ return this.job; } } //请看这里 咱们新建一个对象 var person1=new Person('nicolas',29,'software engineer'); var person2=new Person('jack',29,'software engineer'); person1.getName(); // nicolas person2.getName();// jack
到此为止 咱们做一个实验:alert(person1.sayName==person2.sayName) //输出为false.
不是同一个函数对象这似乎很许多强类型语言 比如java和c#类似 声明类的属性 然后设置getset方法去调用
但是 为每一个对象都去初始化这样 “执行同一个动作”的函数对象 是否合乎情理呢,这样我们就自然而然想到了j
ava中的静态关键字,
我们姑且可以将prototype理解为静态的成员或者方法,new的对象是共享的,这样我们就会节约内存?
二,再来看原型模式创建对象
function Person(){ } Person.prototype.name='nicolas'; Person.prototype.age=29; Person.prototype.job='software engineer'; Person.prototype.sayName=function(){ return this.name }
//请看这了 咱们还是新建两个对象 var person1=new Person(); var person2=new Person(); person1.getName();//nicolas person2.getName();//nicolas</span>到此为止,咱们仍旧做这个同上的实验 alert(person1.sayName==person2.SayName);//输出为true,是同一个对象重点(理解不到也没关系,楼主也是有点晕)构造函数,原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针 ,而每个实力都包含一个指向原型对象的内部指针。现在我们以第二个声明函数的方式来做个例子:
var person1=new Person(); var person2=new Person(); person1.name="Jack"; alert(person1.name);//Jack alert(person2.name);//nicolas
这时候大家就会奇怪,不是说原型里面都是共享的吗?为什么person2输出的还是原型设置的nicolas 而不是Jack;请注意:这里我们为person1的name设置了新的值后; "如果我们在实例中添加了一个属性,并且该属性与实例原型中的一个实例重名 ,那我们就是在实例中创建了该属性,换句话说就是:person1.name='Jack';这一句代码表示了这个name是属于实例的属性.它会阻止我们去访问实例的原型中的nicolas";当然我们也可以通过代码delete
person1.name; 去删除person1.name这个实例属性,执行了这局代码后:
alert(person1.name);//nicolas 原型属性
javascript里面有很多判断属性是属于实例或者原型的,请大家自行搜索。
三,更加简单的原型语法:以字面量形式创建原型对象
function Person(){ } Person.prototype={ name="nicolas", age=29, job="software engineer", getName=function(){ return this.name; } }</span>第二大点中说过,每创建一个函数就会同时创建他的prototype对象,这个对象也会自动获得constructor属性(指向构造函数的指针);但是这里constructor属性不再指向Person了,这里我们使用的字面量声明方式本质上完全重写了默认的prototype对象,指向构造函数的指针不会指向原来Person,而是Object.
//如果原型指向构造函数的指针真的这么重要,请像下面这样声明: function Person(){ } Person.prototype={ constructor:Person, name:"nicolas", age:29, job:"software engineer", getName:function(){ return this.name; } } //但是这种方式重新设置constructor属性会导致它的[Enumerable]属性设置为true.默认情况下原生的constructor属性是不可枚举的, //因此如果你是用兼容ECMAScript5的javascript引擎 请像下面这样声明:
function Person(){ } Person.prototype={ name:"nicolas", age:29, job:"software engineer", getName:function(){ return this.name; } } Object.defineProperty(Person.prototype,"constructor",{ enumerable:false, value:Person })四, 在第三点中提到了用表达式方式声明prototype会或重写默认的prototype对象,这就引出了这一个话题:原型的动态性
<span style="font-size:12px;"> var friend=new Person(); Person.prototype.sayHello=function(){ alert('Hello~') } friend.sayHello();//不会报错 //但是 若是这样 function Person(){} var friend=new Person(); Person.prototype={ ...something sayHello:function(){ alert('Hello~') } } friend.sayHello();//error</span>用表达式这种方法添加sayHello(),重写了整个prototype 但是当下的friend对象仍然是指向原来的原型,当我们原型整个修改就相当于把原型修改为另外一个对象了,切断了构造函数与最初原型之间的联系。请记住 实例中的指针仅仅指向原型,而不指向构造函数。 相当于当前friend指向的原型 和我们重新写的没有任何关系~
五,原型存在的问题
最重要的问题就是 共享的属性若是引用类型,只要任何实例一改动,原型里面的内容也会改动;
function Person(){} Person.prototype={ name:"nicolas", job:'software engineer', age;29, friends:['sheldon','Lenard'] }; var person1=new Person(); var person2=new Person(); person1.friends.push('Nianlu'); alert(person1.friends);// sheldon,Lenard,Nianlu alert(person2.friends);// sheldon,Lenard,Nianlu //再看,他们引用的是否是同一个数组 alert(person1.friends==person2.friends) //true
六,组合使用构造函数和原型模式
//既然两种模式各有优缺点,我们就把两者结合到一起,请看下面的例子 function Person(name,job,age){ this.name=name; this.job=job; this.age=age; this.friends=['Sheldon','Lenard']; } Person.prototype={ constructor:Person, sayHello:function(){ alert('Hello~'); } } var person1=new Person('nicolas','software engineer',29); var person1=new Person('jack','software engineer',29); person1.friends.push('Kimkadasion'); alert(person1.friends);// sheldon,Lenard,Kimkadasion alert(person2.friends);// sheldon,Lenard alert(person1.friends==person2.friends) //false alert(person1.sayHello==person2.sayHello) //true
结束~
相关文章推荐
- 【javascript笔记】关于函数的构造函数和prototype
- 【javascript笔记】 函数内部属性以及方法<三>
- 【javascript笔记】声明函数的三种方式<二>
- D3.JS 基于javascript的图表展示库<四>----基本元素选择与Table
- Java笔记3 多线程<1>线程概述、多线程的创建、多线程的安全问题、静态同步函数的锁、死锁
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<Oracle_函数_触发器_游标_存储过程_视图>(三十五)
- PostgreSQL学习笔记6之函数和操作符<二>
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<SQL_Server_视图_函数_存储过程_触发器等>(二十三)
- Java笔记1 Java编程基础<2>循环语句、函数(重载)、变量和数组的内存结构
- <C++学习笔记>函数模板 template
- 关于<a href='javascript:function()'>
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<javascript>(三十)
- LDAP学习笔记<一>关于LDAP协议及其基本概念
- hadoop学习笔记<四>----map-reduce工作原理
- <<javascript 高效图形编程>>笔记
- 【javascript 笔记】<一>
- 关于<a href='javascript:function()'>
- <高性能JavaScript>笔记 [4~6]
- <<c++ primer>> 函数指针的笔记
- javascript学习笔记——如何修改<a href="#">url name</a>