var person = {}
Object.defineProperty(person,'name',{
writable:false,
value : 'Nike'
})
console.log(person.name);
person.name = 'Gray';
console.log(person.name);
console.log(person);
function Person(name,age,job){
var obj = new Object()
obj.name = name
obj.age = age
obj.job = job
obj.sayName = function(){
console.log(this.name);
}
return obj;
}
var person = Person('Loly',13,'程序员');
person.sayName() //Loly
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
}
创建Person的新实例,必须使用new操作符
1、创建一个新对象
2、将构造函数的作用域赋给新对象
3、执行构造函数中的代码
4、返回新对象
var person = new Person('Ahad',23,'sad')
person.sayName()
console.log(person.constructor == Person);//true
console.log(person instanceof Object);//true
console.log(person instanceof Person);//true
function Person(){
}
Person.prototype.name = "Mike";
Person.prototype.age = 12;
Person.prototype.sayName = function(){
console.log(this.name);
}
var person = new Person();
var otherperson = new Person();
console.log(person.sayName == otherperson.sayName)//true 属性和方法是绑定在原型上的,是可共享的
//getPrototypeOf返回的对象是这个对象的原型
Object.getPrototypeOf(person);//Person
//isPrototypeOf()方法:确定对象之间是否存在原型和实例关系
Person.prototype.isPrototypeOf(person);//true
//hasOwnProperty():检测一个属性是否存在于实例中
person.name = 'Gery'
console.log(person.hasOwnProperty('name'));//true 此时name来自实例
delete person.name
console.log(person.hasOwnProperty('name'));//false 此时name来自原型,实例没有属于自己的name属性
//原型与in操作符( 无论该属性存在于实例还是原型 )
console.log('name' in person);//true name来自原型
person.name = 'Gery'
console.log('name' in person);//true name来自实例
//hasOwnProperty和in操作符合作判断属性是原型的还是实例对象的
function hasPrototypeProperty(object,name){
return !object.hasOwnProperty(name) && (name in object);
}
function Per(){}
Per.prototype.name = 'Mike'
var per = new Per();
console.log(hasPrototypeProperty(per,'name'));
//true per.hasOwnProperty(name)是0,取反为1,1&&1=1,name属于原型
per.name = 'Dike'
console.log(hasPrototypeProperty(per,'name'));
//false per.hasOwnProperty(name)是1,取反为0,1&&0=0,name属于实例
//Object.keys()返回一个包含所有可枚举属性的字符串数组
Object.keys(Person.prototype); //['name', 'age', 'sayName']
Object.keys(person); //['name', 'age', 'sayName']
//Object.getOwnPropertyNames返回所有实例属性
Object.getOwnPropertyNames(Person.prototype); //['constructor', 'name', 'age', 'sayName']
Object.getOwnPropertyNames(person); //['name', 'age', 'sayName']
//更简单的原型语法
function People(){
}
People.prototype = {
// constructor:People,
name:'KKK',
age:19,
job:'boss',
sayName:function(){
console.log(this.name);
}
}
var friend = new People()
console.log(friend.constructor);
//ƒ Object()
//此时的constructor不再指向People,而是指向Object构造函数,如果constructor很重要,可以设置constructor:People,如上所示,此时[[Enumerble]]特性被设置为true
//重设构造函数,只适用于ECMAScript5兼容的浏览器
Object.defineProperty(People.prototype,'constructor',{
enumerable:false,
value:People
})
console.log(friend.constructor); //f People(){}
//原型的动态性
//1、
function People(){
}
People.prototype = {
constructor:People,
name:'KKK',
age:19,
job:'boss',
sayName:function(){
console.log(this.name);
}
}
var friend = new People()//创建
People.prototype.sayNo = function(){console.log("NoNoNo");}
friend.sayNo()//NoNoNo
function People1(){ //1
}
var friend1 = new People1();//创建实例 引用的是原来的原型,此时创建的friend实例没有sayName方法
People1.prototype = { //2、重写了原型
constructor:People1,
name:'KKK',
age:19,
job:'boss',
sayName:function(){
console.log(this.name);
}
}
var friend2 = new People1(); //创建实例 引用的是重写后的原型,此时创建的friend2实例有sayName方法
friend1.sayName() //error 报错
friend2.sayName() //KKK
//原型对象问题
People.prototype.friends = ['a','b']
var friend3 = new People()
var friend4 = new People()
friend3.friends.push('c') //friend3修改了原型中共享的friends属性,这时friend4指向的同一个friends也更改了
console.log(friend3.friends);//['a', 'b', 'c']
console.log(friend4.friends);//['a', 'b', 'c']
function Unite(name,age,job){
this.name = name
this.age = age
this.job = job
this.friends = ['She','He']
}
Unite.prototype = {
constructor:Unite,
sayName:function(){
console.log(this.name);
}
}
var unite1 = new Unite('YY',18,'cooker')
var unite2 = new Unite('ZZ',21,'painter')
unite1.friends.push('It') //修改的是实例的属性
console.log(unite1.friends);//['She', 'He', 'It']
console.log(unite2.friends);//['She', 'He']
console.log(unite1.friends == unite2.friends);//false
console.log(unite1.sayName == unite2.sayName);//true
(不能使用对象字面量重写原型)
function DynamicPrototype(name,age){
this.name = name
this.age = age
//方法
if(typeof this.sayName != "function"){
DynamicPrototype.sayName = function(){
console.log(this.name);
}
}
}
console.log(DynamicPrototype.prototype);
var dp = new DynamicPrototype('SS',32)
function ParasiticModels(name,age,job){
var obj = new Object()
obj.name = name
obj.age = age
obj.job = job
obj.sayName = function(){
console.log(this.name);
}
return obj;
}
var parasiticModels = new ParasiticModels('寄生',13,'程序员');
parasiticModels.sayName() //Loly
创建对象的实例方法时不引用this,不使用new操作符调用构造函数
function SafeModel(name,age,job){
var obj = new Object();
//可以在这里定义私有变量和函数
//添加方法
obj.sayName = function(){
console.log(name);
};
return obj;
}
var safeModel = SafeModel('稳妥',21,'boss')
safeModel.sayName() //只能访问到sayName()方法,无法访问其他数据成员