Many friends will encounter difficulties in object creation when learning the front-end. Let me teach you some methods. I hope you will learn patiently.
1. Method of creating an object
1. Factory pattern
Create an object in a function and give this Add properties to the object and then return the object in this function. Call this function outside a function to create an instance of the object.
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");
Problem: The object identification problem is not solved (the type of an object cannot be known)
2. Constructor pattern (can be used to create objects of a specific type)
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");
Differences from the factory pattern:
(1) No explicit creation of objects
(2) Directly assign properties and methods to the object pointed to by this
(3) There is no return statement
Both instances have a constructor attribute pointing to Person.
The constructor can identify what type of object its instance is, and it is more reliable to use the instanceof operator.
Q: What is the difference between a constructor and an ordinary function?
Answer: The constructor is called using the new operator, and the ordinary function is called without new.
Problem with constructor: Each method must be recreated on each instance.
3. Prototype pattern
The properties and methods shared by object instances are not placed in the constructor, but all in the prototype object.
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
Problem with the prototype pattern: For attributes containing application type values, due to the sharing of the prototype pattern, if the reference type value of one instance is changed, the attribute values of other instances will also be changed. .
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. Combination pattern (constructor and prototype)
The constructor defines the properties of the instance, and the prototype defines methods and shared properties.
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; } Person.prototype={ constructor:Person, sayname:function(){ alert(this.name) } }
1. Understanding
Each constructor Person has a prototype attribute pointing to its prototype object, that is, the prototype object is Person. prototype; and each prototype object has a constructor method that points back to the constructor Person. In addition, the instance person1 created by calling the constructor has a [[Prototype]] attribute (_proto_), which also points to the prototype object of the constructor. Note that the connection occurs between the instance and the prototype object of the constructor! The instance has nothing to do with the constructor.
isPrototypeOf() method: detects whether there is a prototype connection relationship between the prototype object and the instance
Person.prototype.isPrototypeOf(person1);//true
Object.getPrototypeOf() method: This method returns [[ The value of prototype]] returns the prototype object of an instance.
Object.getPrototypeOf(person1);// Person.prototype
Note: Be sure to set the prototype object of the constructor first, and then create a new instance. (Dynamic nature of prototype)
Example:
function Person(){ } var friend=new Person(); Person.prototype={ constructor:Person, name:'Nick', age:29, job:'student', sayName:function () { alert(this.name); } }; friend.sayName();//error
In this case, the prototype of Person is rewritten: p.157
2. Attribute access
Q: What is the role of prototype ([[Prototype]]) reference?
Answer: When referencing the properties of an object, the underlying [[Get]] operation will be triggered. For the default [[Get]] operation, the first step is to check whether the object itself has this attribute. If so, use it. If not, then the [[Prototype]] chain comes in handy. If the object itself does not have the required attribute, it will continue to search along the entire prototype chain. If it is found, the value of the attribute will be returned. If it is not found, undefined will be returned.
for...in... The principle of traversing objects is similar to the search [[Prototype]] chain. When using the in operator to check whether a property exists in an object, the entire prototype chain of the object is also checked (regardless of whether the property is enumerated or not).
[[Prototype]] The top of the prototype chain is set to the Object.prototype object.
3. Attribute setting and shielding
myObject.foo="bar";//设置属性foo
step1: When there is an attribute foo in the myObject object, directly modify foo to "bar";
step2 : When the foo attribute exists in both myObject and the prototype chain, the foo attribute on myObject will block all foo attributes on the prototype chain;
step3: When there is no foo attribute in the myObject object, then Will search up the prototype chain that exists in myObject;
3.1 If the foo attribute exists in the upper layer of the [[Prototype]] chain, and it is not marked as read-only (writable: false), then add it directly on myObject A foo property, which is a shielded property;
var myObject={ }; myObject.prototype={ foo:"c" }; myObject.foo="b"; console.log(myObject.foo);//b
3.2 If the foo property is marked as read-only, you cannot modify existing properties or create shielded properties on myObject. If in strict mode an error will be thrown.
var myObject={ }; myObject.prototype={ foo:"c" }; Object.defineProperty(myObject,"foo",{ writable:false }) myObject.foo="b"; console.log(myObject.foo);//undefined
3.3 If foo exists on [[Prototype]] and is a setter, this setter will definitely be called. foo will not be added to myObject, nor will the setter of this property be redefined.
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面向对象
The above is the detailed content of Learn how to create an object's methods and prototype objects. For more information, please follow other related articles on the PHP Chinese website!