>웹 프론트엔드 >JS 튜토리얼 >객체의 메소드와 프로토타입 객체를 생성하는 방법을 알아보세요.

객체의 메소드와 프로토타입 객체를 생성하는 방법을 알아보세요.

坏嘻嘻
坏嘻嘻원래의
2018-09-13 16:11:021870검색

프런트엔드를 배울 때 많은 친구들이 객체 생성에 어려움을 겪을 것입니다. 몇 가지 방법을 가르쳐 드리겠습니다.

1. 객체 생성 방법

1. 팩토리 패턴

함수에서 객체를 생성하고 객체에 속성을 추가한 후 함수에서 객체를 반환합니다. 객체의 인스턴스를 생성하려면 함수 외부에서 이 함수를 호출하세요.

function createPerson(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=createPerson("xiaowang","22","workers");//在函数外部创建对象的实例,不用new
var person1=createPerson("xiaoliu","22","workers");

문제: 객체 식별 문제가 해결되지 않음(객체의 유형을 알 수 없음)

2. 생성자 패턴(특정 유형의 객체를 생성하는 데 사용할 수 있음)

function Person(name,age,job){//注意构造函数开头的字母应该大写
//构造函数中使用this
   this.name=name;
   this.age=age;
   this.job=job;
   this.sayName=function(){
   alert(this.name);
   }
}
var person1=new Person("xiao",22,"tech");//使用new创建实例
var person2=new Person("li",32,"sin");

팩토리 패턴과의 차이점 :

(1) 생성된 객체가 표시되지 않습니다

(2) this가 가리키는 객체에 속성과 메소드를 직접 할당합니다

(3) return 문이 없습니다

두 인스턴스 모두 생성자 속성을 가집니다. 사람을 가리키는.

생성자는 인스턴스가 어떤 객체 유형인지 식별할 수 있으며, instanceof 연산자를 사용하는 것이 더 안정적입니다.

Q: 생성자와 일반 함수의 차이점은 무엇인가요?

답변: 생성자는 new 연산자를 사용하여 호출되며 일반 함수는 new 없이 호출됩니다.

생성자 관련 문제: 각 메서드는 각 인스턴스에서 다시 생성되어야 합니다.

3. 프로토타입 패턴

객체 인스턴스가 공유하는 속성과 메서드를 생성자가 아닌 프로토타입 객체에 넣습니다.

function Person(){  };//构造函数什么也不设置
Person.prototype.name="xiao";//全部都放在原型对象上
Person.prototype.age=22;
Person.prototype.job="stu"'
Person.prototype.sayName=function(){
   alert(this.name);
}

var person1=new Person();
var person2=new Person();
console.log(person1.sayName==person2.sayName);//true

프로토타입 패턴 문제: 애플리케이션 유형 값을 포함하는 속성의 경우 프로토타입 패턴 공유로 인해 한 인스턴스의 참조 유형 값이 변경되면 다른 인스턴스의 속성 값도 변경됩니다.

function Person={}
Person.prototype={
   constructor:Person,
   name:"Nick",
   age:29,
   friends:['a','b'];//引用类型的值
   sayName:function(){
     alert(this.name);
  }
}
var  person1=new Person();
var  person2=new Person();
//想要改变person1实例的friends属性
person1.friends.push("c);
alert(person1.friends);//["a","b","c"]
alert(person2.friends);//["a","b","c"];
alert(person1.friends==person2.friends);//true;

4. 조합 패턴(생성자와 프로토타입)

생성자는 인스턴스의 속성을 정의하고, 프로토타입은 메서드와 공유 속성을 정의합니다.

function Person(name,age,job){
  this.name=name;
  this.age=age;
  this.job=job;
}

Person.prototype={
  constructor:Person,
  sayname:function(){
    alert(this.name)
 }
}

2. 프로토타입 객체의 이해

1. 이해

각 생성자 Person에는 프로토타입 객체를 가리키는 프로토타입 속성이 있습니다. 즉, 프로토타입 객체는 Person.prototype입니다. 생성자 Person을 다시 가리킵니다. 또한 생성자를 호출하여 생성된 person1 인스턴스에는 생성자의 프로토타입 객체를 가리키는 [[Prototype]] 속성(_proto_)이 있습니다. 인스턴스와 생성자의 프로토타입 객체 사이에 연결이 발생한다는 점에 유의하세요 ! 인스턴스는 생성자와 아무 관련이 없습니다.

객체의 메소드와 프로토타입 객체를 생성하는 방법을 알아보세요.

isPrototypeOf() 메소드: 프로토타입 객체와 인스턴스가 프로토타입 연결 관계를 가지고 있는지 감지

Person.prototype.isPrototypeOf(person1);//true

Object.getPrototypeOf() 메소드: 이 메소드는 프로토타입 객체를 반환하는 [[prototype]] 값을 반환합니다. 인스턴스의.

Object.getPrototypeOf(person1);// Person.prototype

참고: 생성자의 프로토타입 객체를 먼저 설정한 다음 새 인스턴스를 생성하세요. (프로토타입의 역학)

예:

function Person(){ }
    var friend=new Person();
    Person.prototype={
        constructor:Person,
        name:'Nick',
        age:29,
        job:'student',
        sayName:function () {
            alert(this.name);
        }
    };
    friend.sayName();//error

이 경우 Person의 프로토타입이 다시 작성됩니다: p.157

2. 속성 액세스

Q: 프로토타입([[프로토타입]]) 참조 무엇을 합니까? 그렇죠?

답변: 개체의 속성을 참조할 때 기본 [[Get]] 작업이 트리거됩니다. 기본 [[Get]] 작업의 경우 첫 번째 단계는 객체 자체에 이 속성이 있는지 확인하는 것입니다. 그렇다면 이 속성을 사용하세요. 그러면 [[Prototype]] 체인이 유용합니다. 객체 자체에 필수 속성이 없는 경우 전체 프로토타입 체인을 따라 계속 검색하며, 해당 속성이 없으면 해당 속성 값을 반환합니다.

for...in... 객체 탐색의 원리는 검색 [[Prototype]] 체인과 유사합니다. 객체에 속성이 존재하는지 확인하기 위해 in 연산자를 사용할 때 객체의 전체 프로토타입 체인도 검사됩니다(속성이 열거되는지 여부에 관계없이).

[[Prototype]] 프로토타입 체인의 상단은 Object.prototype 객체로 설정됩니다.

3. 속성 설정 및 보호

myObject.foo="bar";//设置属性foo

1단계: myObject 객체에 foo 속성이 있는 경우 foo를 "bar"로 직접 수정합니다.

2단계: myObject와 프로토타입 체인 모두에 foo 속성이 존재하는 경우 foo 속성 on myObject는 프로토타입 체인의 모든 foo 속성을 차단합니다.

3단계: myObject 객체에 foo 속성이 없으면 검색되어 myObject의 프로토타입 체인에 존재합니다. 3.1 If [[Prototype]] foo 속성은 체인의 상위 레이어에 존재하며 읽기 전용으로 표시되지 않습니다(쓰기 가능: false). 그러면 보호된 속성인 myObject에 foo 속성을 직접 추가합니다.

var myObject={ };
myObject.prototype={
   foo:"c"
};
myObject.foo="b";
console.log(myObject.foo);//b

3.2 foo 속성이 있는 경우; 읽기 전용 읽기로 표시되면 기존 속성을 수정하거나 myObject에서 보호된 속성을 생성할 수 없습니다. 엄격 모드에서는 오류가 발생합니다.

var myObject={

};
myObject.prototype={
  foo:"c"            
};
Object.defineProperty(myObject,"foo",{
    writable:false
})
myObject.foo="b";
console.log(myObject.foo);//undefined

3.3 foo가 [[Prototype]]에 존재하고 setter라면 이 setter는 반드시 호출될 것입니다. foo는 myObject에 추가되지 않으며 이 속성의 setter도 재정의되지 않습니다.

var myObject={ };
myObject.prototype={
 //foo是一个setter
  set foo(val){
     alert(this.val);
  }
}
myObject.foo="f";
console.log(myObject.foo)//f  foo还是原来的setter函数,没有被修改

   如果在3.2和3.3这两种情况下,则不能使用=操作符在赋值,而是使用Object.defineProperty(...)方法来添加,

step4:如果myObject对象和原型链上都没有foo属性的时候,直接添加到myObject上。

var myObject={ };
myObject.prototype={
   foo:"c"
};
myObject.foo="b";
console.log(myObject.foo);//b

4.属性的修改

   对象实例可以修改对象原型的属性值吗?

  答:分两种情况:一:当原型里的属性是值类型的话,不会被修改;   

 function ClassA(){};
   ClassA.prototype.num=4;//num为值类型
   const a=new ClassA();
   a.num=3;
   const b=new ClassA();
   console.log(b.num);

    二:当原型里的属性是引用类型的话,则会被修改。    

function ClassA(){};
   ClassA.prototype.obj={
       num:4//num在object中,是引用类型
   };
   const a=new ClassA();
   a.obj.num=3;
   const b=new ClassA();
   console.log(b.obj.num);

 相关推荐:

JavaScript 基于原型的对象(创建、调用)_js面向对象

 js如何创建对象?js中创建对象的方法(附代码)

위 내용은 객체의 메소드와 프로토타입 객체를 생성하는 방법을 알아보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.