De nombreux amis rencontreront des difficultés dans la création d'objets lors de l'apprentissage du front-end. Laissez-moi vous apprendre quelques méthodes, j'espère que vous apprendrez patiemment.
1. Méthode de création d'un objet
1. Modèle d'usine
Créer un objet dans une fonction et donner ceci Ajoutez des propriétés à l'objet, puis renvoyez l'objet dans cette fonction. Appelez cette fonction en dehors d'une fonction pour créer une instance de l'objet.
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");
Problème : Le problème de reconnaissance d'objet n'est pas résolu (le type d'un objet ne peut pas être connu)
Modèle de constructeur (peut être utilisé pour créer des objets spécifiques). types)
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");
Différences par rapport au modèle d'usine :
(1) Créer des objets sans affichage
(2) Attribuer directement des attributs et des méthodes à ce objet pointé vers
(3) Il n'y a pas d'instruction return
Les deux instances ont un attribut constructeur pointant vers Person.
Le constructeur peut identifier de quel type d'objet est son instance, et il est plus fiable d'utiliser l'opérateur instanceof.
Q : Quelle est la différence entre un constructeur et une fonction ordinaire ?
Réponse : Le constructeur est appelé à l'aide de l'opérateur new et la fonction ordinaire est appelée sans new.
Problème avec les constructeurs : Chaque méthode doit être recréée sur chaque instance.
3. Modèle de prototype
Mettez les propriétés et méthodes partagées par les instances d'objet non pas dans le constructeur, mais dans l'objet prototype.
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
Problèmes avec le modèle de prototype : pour les attributs contenant des valeurs de type d'application, en raison du partage du modèle de prototype, si la valeur de type de référence d'une instance change, les valeurs d'attribut des autres instances seront le changement a également été modifié.
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. Modèle de combinaison (constructeur et prototype)
Le constructeur définit les propriétés de l'instance, le prototype définit les méthodes et les propriétés partagées.
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; } Person.prototype={ constructor:Person, sayname:function(){ alert(this.name) } }
1. Compréhension
Chaque constructeur Personne a un attribut prototype pointant vers son objet prototype, c'est-à-dire que l'objet prototype est Person.prototype ; et chaque objet prototype a une méthode constructeur qui renvoie au constructeur Person. De plus, l'instance person1 créée en appelant le constructeur possède un attribut [[Prototype]] (_proto_), qui pointe également vers l'objet prototype du constructeur. Notez que la connexion s'effectue entre l'instance et l'objet prototype du constructeur ! Et les instances n'ont rien à voir avec les constructeurs.
Méthode isPrototypeOf() : détecte si l'objet prototype et l'instance ont une relation de connexion prototype
Person.prototype.isPrototypeOf(person1);//true
Méthode Object.getPrototypeOf() : cette méthode renvoie La valeur de [[prototype]] renvoie l'objet prototype d'une instance.
Object.getPrototypeOf(person1);// Person.prototype
Remarque : assurez-vous de définir d'abord l'objet prototype du constructeur, puis de créer une nouvelle instance. (Caractère dynamique du prototype)
Exemple :
function Person(){ } var friend=new Person(); Person.prototype={ constructor:Person, name:'Nick', age:29, job:'student', sayName:function () { alert(this.name); } }; friend.sayName();//error
Dans ce cas, le prototype de Personne est réécrit : p.157
2. Accès aux attributs
Q : Quel est le rôle de la référence du prototype ([[Prototype]]) ?
Réponse : Lors du référencement des propriétés d'un objet, l'opération [[Get]] sous-jacente sera déclenchée. Pour l'opération [[Get]] par défaut, la première étape consiste à vérifier si l'objet lui-même possède cet attribut. Si tel est le cas, utilisez-le. Sinon, la chaîne [[Prototype]] est utile. Si l'objet lui-même n'a pas l'attribut requis, il continuera à rechercher tout au long de la chaîne de prototypes. S'il est trouvé, la valeur de l'attribut sera renvoyée. S'il n'est pas trouvé, undéfini sera renvoyé.
for...in... Le principe du parcours des objets est similaire à la chaîne de recherche [[Prototype]]. Lorsque vous utilisez l'opérateur in pour vérifier si une propriété existe dans un objet, toute la chaîne de prototypes de l'objet est également vérifiée (que la propriété soit énumérée ou non).
[[Prototype]] Le haut de la chaîne de prototypes est défini sur l'objet Object.prototype.
3. Définition et blocage des attributs
myObject.foo="bar";//设置属性foo
étape 1 : Lorsqu'il y a un attribut foo dans l'objet myObject, remplacez directement foo par "bar"
étape 2 ; : Lorsque l'attribut foo existe à la fois dans myObject et dans la chaîne prototype, l'attribut foo sur myObject bloquera tous les attributs foo sur la chaîne prototype ;
étape 3 : Lorsqu'il n'y a pas d'attribut foo dans l'objet myObject, il le fera. rechercher et exister dans la chaîne de prototypes de myObject ;
3.1 Si l'attribut foo existe dans la couche supérieure de la chaîne [[Prototype]] et qu'il n'est pas marqué en lecture seule (inscriptible : false) , puis sur myObject Ajoutez directement un attribut foo, qui est un attribut protégé ;
var myObject={ }; myObject.prototype={ foo:"c" }; myObject.foo="b"; console.log(myObject.foo);//b
3.2 Si l'attribut foo est marqué comme en lecture seule, vous ne pouvez pas modifier les attributs existants ou créer des attributs protégés sur monObjet. Si vous êtes en mode strict, une erreur sera générée.
var myObject={ }; myObject.prototype={ foo:"c" }; Object.defineProperty(myObject,"foo",{ writable:false }) myObject.foo="b"; console.log(myObject.foo);//undefined
3.3 Si foo existe sur [[Prototype]] et est un setter, ce setter sera définitivement appelé. foo ne sera pas ajouté à myObject et le setter de cette propriété ne sera pas redéfini.
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面向对象
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!