JavaScript: オブジェクトの作成 (プロトタイプ パターンとコンストラクター パターン)

JavaScript: オブジェクト

1. オブジェクトを理解する

var person = {
    
    }

Object.defineProperty(person,'name',{
    
    

  writable:false,

  value : 'Nike'

})

console.log(person.name);

person.name = 'Gray';

console.log(person.name);

console.log(person);

2. オブジェクトの作成

2.1. ファクトリーモード

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

2.2. コンストラクターパターン

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

2.3. プロトタイプモード

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']

2.4. コンストラクターパターンとプロトタイプパターンの併用

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

2.5. 動的プロトタイプモード

(プロトタイプはオブジェクト リテラルを使用してオーバーライドできません)

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)

2.6. 寄生コンストラクターパターン

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

2.7. 安全なコンストラクターパターン

オブジェクトのインスタンス メソッドを作成するときにこれを参照したり、コンストラクターを呼び出すために 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()方法,无法访问其他数据成员

おすすめ

転載: blog.csdn.net/m0_47147246/article/details/125800166