1、理解对象
var
person=
new
Object();
person.
name=
"yue";
person.
age=
21;
person.
sayname=
function(){
alert(
this.
name);
var
perron={
name:
"yue",
age:
21,
sayname:
function(){
alert(
this.
name);
}
};
};
属性类型:(大多数情况下不用高级)
configurable:是否可以删除属性,是否修改属性的特性,能否把属性修改为访问其属性。默认为true;
enumerable:能否通过for-in循环返回属性。默认为true;
writable:是否可以修改属性,默认为true。
value:属性被读取或写入的值都在value里查看。默认为undefined
writable
var person={ };
Object.definePropery(person,"name",{
writable:false,
value:"meimei"
});
alert(person.name); //meimei
person.name="geg"; //修改属性
alert(person.name); //meimei 属性值没被改变
configurable
var person={};
Object.definePropety(person,"name",{
configurable:false,
value:"lele"
});
alert(person.name); //lele
delete person.name; //删除属性 费严格模式下什么都不会发生,但是在严格模式下会抛出异常
alert(person.name); //lele configurable:false; 顒属性不能被删除
//一旦属性定义为不可配置的,就不能把它变为可配置得了,再调用Object.defineProperty方法修改除writable以外的特性,都会导致错误。
var person={};
Object.definePropety(person,"name",{
configurable:false,
value:"lele"
});
//抛出异常
var person={};
Object.definePropety(person,"name",{
configurable:true,
value:"lele"
});
工厂模式
function a(name,age,job){
var person=new Object();
person.name=name;
person.age=age;
person.job=job ;
person.sayname=function (){
alert(this.name);
}
return person;
}
var persn2=a("qq",21,"software");
var person3=a("ww",23,"enginner");
构造函数模式
构造函数:1、没有显示的创建函数;2、直接将属性和方法赋给了this值;3、没有return语句。
function Aa(){
this.name=name;
this.job =job ;
this.age=age;
this.sayname=function (){
alert(this.name);
}
}
var person1=aa("huhua","art",32);
alert(person1.constructor==person); //true
当做构造函数使用
var person=new Person("ff",11,"ww");
person.sayname(); //ff
作为普通函数使用
person(“rew”,22,"ggg");
window.sayname(); //rew
在另一个对象的作用域中调用
var o=new Object();
person.call(o,“rew”,22,"ggg"); //通过call()方法,将原本属于对象person的方法交给d对象o使用。
o.sayname(); //rew
原型模式
person(){}
person.prototype.name="lele";
person.prototype.age=12;
person.prototype.job="start";
person.prototype.sayName=function(){
alert(this.name);
}
var person1=new Person();
person1.sayName(); //"lele"
var person2=new Person();
person2.sayName(); //"lele"
alert(person1.sayName==person2.sayName); //true
isPrototypeOf()
alert(person.prototype.isPrototypeOf(person1)); //true
alert(Object.getPrototypeOf(person1)==person.prototype); //true 原型
alert(Object.getPrototypeOf(person1).name); //"lele" 访问原型的属性
var person3=new person();
person3.name="mingming";
alert(person3.name); //"mingming" 来自实例
alert(“”name“ in person3) //true name属性来自实例 无论name属性来自原型还是对象实例都返回true
delete person3.name;
alert(person3.name); //"lele" 来自原型
alet("name" in person3) //true 无论name属性来自原型还是对象实例都返回true
hasOwnPrototype()检测一个属性是否来自实例
person1.hasOwnPrototype("name"); //false 因为来自原型
person1.name="qqqqq";
person1.hasOwnPrototype("name"); //true 来自实例
确定属性存在原型中
function qq(){
return !Object.hasOwnProperty(name)&&(name in object); // !object.hasOwnProperty(name)确定属性只存在原型中,name in object确定属性可以访问(存在对象、原型中都可以访问)
}
var person6=new person();
alert(qq(person6,"name")); //true 存在原型中
var person7=new person();
person.name="fvfv";
alert(qq(person7,"name")); //false 存在实例中
获取对象上所有可枚举的实例属性
var keys=Object.keys(person.prototype);
alert(keys); //name,age,job,sayName
var person10=new person();
person10.name="huang";
person.age=32;
var keys_person10=Object.keys(person10);
alert(keys); //name,age
Object.getOwnPropertyNames()获取对象上所有实例的属性,不管是否可枚举
var keys=Object.getOwnPropertyNames(person.prototype);
alert(keys); //name,age,job,sayName,constructor
更简单的原型语法
function person(){}
person.prototype={
name="lele";
age="21";
job="ewe";
sayname=function(){alert(this.name)}
}
var friend= new person();
alert(friend instanceof Object); //true
alert(friend instanceof person); //true
alert(friend.constructor==person); //false 简单原型模式与原型模式相比有一个例外,就是constructor属性不再指向person了。
alert(friend.constructor==object); //true
如果constructor很重要,将它设置回适当值
function person(){}
person.prototype={
construtor:person;
name="lele";
age="21";
job="ewe";
sayname=function(){alert(this.name)}
}
访问器其属性不包含数据值,它们包含get和 set函数(不过这两汉函数都不是必需的),读取访问器属性是,会调用get函数,这个函数负责返回有效的值;在写入访问器属性时,
var person={year:2017;edition=1};
Object.defineProperty(person,"year",(
get:function(){
return this._year;
};
set:function(newvalue){
if(newvalue>2017)
this._year=newvalue;
this.edition+=newvalue-2017;
}
));
person.year=2018;
alert(person.edition); 2
var book={};
Object.defineproperties(book,(
_year:{
value:2017
},
edition:{
value:1
},
year:{
get:function(){
return this._year;
}
},
set:function(newvalue){
if(newvalue){
this._year=newvalue;
this.edition+=newvalue-2017;
}
}
));
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
alert(descriptor.value); //2017
alert(descriptor.configurable); //false
alert(typeof descriptor.get ); //"undefine"
var descriptor=Object.getOwnPropertyDescriptor(book,"year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function"
创建对象
工厂模式
function creatrperson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayname=function(){
alert(this.name);
}
return o;
}
var person1=creatrperson("qq",12,"engineer");
var person2=creatrperson("ww",43,"engineer2");
构造函数模式(没创建对象,直接将属性和方法赋给了this,没return返回值)
function creatrperson(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayname=function(){
alert(this.name);
}
}
var person1=new creatrperson("qq",12,"engineer");
person1.sayname(); //qq
var person2=new creatrperson("ww",43,"engineer2");
alert(person1.constructor==person) //true person1、person2分别保存着person的一个不同的实例,这两个对象都有一个constructor属性,该属性指向person
aler(person1 instanceof person); //true
aler(person1 instanceof Object); //true
不同实例上的同名函数是不相等的
alert(person.sayname=person2.sayname) //false
function person(name,age,job){
this.name=name;
this.age=age;
thia.job=job;
this.sayname=sayname; //讲say那么属性设置成等于全局的sayname函数
}
function sayname(){
alert( this.name);
}
var person1=new person("ee",90,"enginner");
原型模式
function Person(){ };
Persnn.prototype.name="fd";
Persnn.prototype.job="enginner";
Persnn.prototype.age=32;
Persnn.prototype.sayName=function(){
alert(this.name);
};
person1=new Person();
person1.sayName(); //"fd"
person2=new Person();
person2.sayName(); //"fd"
alert(person1.sayName==person2.sayName) //true
alert(person1.prototype.isPrototypeOf()person); //true
alert(Object.getPrototype(person1)==Person.prototype) //true
alert(Object.getPrototype(person1).name); //"fd"
person3=new Person();
person3.name="meimei";
alert(person3.name); //"meimei" //在实例中创建的属性会屏蔽原型中对应的属性
delete person3.name;
alert(person3.name); //"fd" 删除实例中的属性后恢复对原型中属性的连接
检测一个属性是存在于实例中 不存在于原型中
function Person(){ };
Persnn.prototype.name="fd";
Persnn.prototype.job="enginner";
Persnn.prototype.age=32;
Persnn.prototype.sayName=function(){
alert(this.name);
};
person1=new Person();
person1.sayName(); //"fd"
person2=new Person();
person2.sayName(); //"fd"
alert(person1.hasOwnProperty("name")); //false 来自原型
person2.name="yue"
alert(person2.hasOwnProperty("name")); //true 来自实例
in操作符通过对象访问属性,不管该属性在实例还是原型中
alert(name in person1); //"fd" 存在于原型中
alert(name in person2); //"meimei" 存在于实例中
确定属性存在与对象中,不存在于原型中。
function yuanXingZhong(object,name){
return !object.hasOwnProperty(name)&&(name in object);
}
var person1=new Person();
alert(yuanXingZhong(person1,name)); //true
var person2=new Person();
person2.name="oo";
alert(yuanXingZhong(person2,name)); //false
获取对象上所有可枚举的属性
function Person(){ };
Persnn.prototype.name="fd";
Persnn.prototype.job="enginner";
Persnn.prototype.age=32;
Persnn.prototype.sayName=function(){
alert(this.name);
};
var keys= Object.key(Person.prototype);
alert(keys); //"name","job","sayName","age" 返回可枚举数组
var p1=new Person();
p1.name="rob";
p1.age=32;
var p1keys=Object.key(p1);
alert(p1keys); //name,age
var keys2=Object.getOwnPropertyNames(Person.prototype);
alert(keys2); //"name","job","sayName","age","constructor" 返回不可枚举数组
将person.prototype设置为等于一个字面量形式创建的新对象,最终结果相同,但constructor属性不再指向person
person(){}
person.prototype={
name:"ff";
job:"enginner";
age:32;
sayName:function(){
alert(this.name);
}
}
var friend= new Person();
alert(friend instanceof person); //true
alert(friend instanceof Object); //true
alert(friend.constructor==person); //false 可以将constructor:person放入person.prototype,变为true
alert(friend.
constructor==Object);
//true
及时person实例是在添加新方法之前创建的,但它仍然可以访问这个新方法,当我们调用
sayHi()时,首先会在实例中搜索名为sayHi的属性,在没找到的情况下,会继续搜索原型
var friend =new Person();
Person.prototype.sayHi=function(){
alert("hy");
}
friend .sayHi(); //"hi"
先创建实例再重写原型,实例不可访问原型的
function Person(){ }
var person1=new person(); //创建实例
var Person.prototype={ //重写原型(把原型修改为另一个对象)
constructor:Person;
name:"vv";
age:51;
job:"dancer";
sayName:function(){
alert(this.name);
}
}
person1.sayName(); //error
通过原生对象的原型,可以取得所有默认方法的引用
alert(typeof Array.prototype.sort); //"function"
alert(typeof String.prototype.substring); //"function"
通过原生对象的原型,还可以定义新方法
String.prototype.startwith=function(text){
return this.indexOf(text)==0;
};
var msg="hello world";
alert(mag.startwith("hello")); //true
原型对象的问题()
function person(){};
person.prototype={
constructor:Person;
name:"vv";
age:51;
job:"dancer";
sayName:function(){
alert(this.name);
friend:["gg","hh"];
}
var person1=new person();
var person2=new person();
person1.friend.push("rr"); //修改了person1.friend引用的数组,向数组中添加了一个字符串,由于friend数组存在于person.prototype中而非person1中,所以也会通过person2.prototype反映出来。(但是实例一般都要有属于自己的全部的属性的,所以很少有人单独使用原型模式)
alert(person1.friends); //"gg,hh,rr"
alert(person2.friends); //"gg,hh,rr"
组合使用构造函数模式和原型函数模式
function Person(name,age,job){
this.name=name;
this.age=age;
thia.job=job;
this.friend=["aa","ss"];
}
Person.prototype={
constructor:person;
sayName:function(){
alert(this.name);
}
}
var person1=new Person("cc",43,"singer");
var person1=new Person("cd",43,"dancer");
person1.friend.push("sa");
alert(person1.friend); //"aa","ss","sa"
alert(person2.friend); //"aa","ss"
alert(person2.friend===person1.friend); //false
alert(person2.sayName===
person1.sayName
); //true
if(typeof this.sayName!="function"){
person.prototype.sayName=function(){
alert(this.name);
}
}
}
var friend=new person("fr",43,"lawyer");
friend.sayname();
寄生构造函数模式
function Person(name,age,job){
var o=new Object();
o.name=name;
o.job=job;
o.age=age;
o.sayName=function(){
alert(this.name);
}
return o;
}
var friend=new person("hj",65,"software");
friend.sayName(); //"hi"
function SpecialArray(){
var value=new Array(); //创建数组
value.push.apply(value,arguments); //添加值
values.toPipedString=function(){ //添加方法
return this.join(“|”);
};
return value; //返回数组
}
var color=new SpecialArray("red","blue","green");
alert(color.
toPipedString()); //"red|blue|green"
稳妥性构造函数模式
稳妥对象指的是没有公共属性,而且其它方法也不引用this的对象。稳妥对象最适合在一些按券环境中(禁止使用new this),或者防止数据被其他应用改动时使用。
function Person(name,age,job){
var o=new Object(); //创建要返回的对象
o.sayNamae=function(){
alert(name);
};
return o; //返回对象
}
var friend = Person ("nn",454,"singer");
friend.sayName(); //"nn"