프런트엔드를 배울 때 많은 친구들이 객체 생성에 어려움을 겪을 것입니다. 몇 가지 방법을 가르쳐 드리겠습니다.
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) } }
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面向对象
위 내용은 객체의 메소드와 프로토타입 객체를 생성하는 방법을 알아보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!