Chapitre 6, Programmation orientée objet
Objet :
1. Attributs des données
configurable, indiquant si l'attribut peut être redéfini en supprimant l'attribut via delete, si les caractéristiques de l'attribut peuvent être modifiées ou si l'attribut peut être modifié en attribut accesseur
.
enumerbale, indiquant si l'attribut est accessible via for-in, la valeur par défaut est true
inscriptible, indiquant si la valeur de l'attribut peut être modifiée, la valeur par défaut est vraie
valeur, emplacement de stockage des données, la valeur par défaut n'est pas définie
Modifiez les caractéristiques de l'attribut par défaut : Object.defineProperty(), qui reçoit trois paramètres : l'objet où se trouve l'attribut, le nom de l'attribut et l'objet descripteur. Les attributs de l'objet descripteur doivent être : configurable, énumérable, inscriptible, valeur
Exemple :
var obj = {}; Object.defineProperty(obj,”name”,{ writable:true, value:”nihao” });
2. Propriétés des accesseurs
configurable, indiquant si l'attribut peut être redéfini en supprimant l'attribut via delete, si les caractéristiques de l'attribut peuvent être modifiées ou si l'attribut peut être modifié en attribut accesseur
.
enumerbale, indiquant si l'attribut est accessible via for-in, la valeur par défaut est true
get, appelé lors de la lecture des attributs, la valeur par défaut n'est pas définie
set, appelé lors de l'écriture des attributs, la valeur par défaut n'est pas définie
La modification doit être effectuée via Object.defineProperty()
Exemple :
var obj = { _year:2004, edition:1 } Object.defineProperty(book,”year”,{ get:function(){ return this._year; }, set:function(newValue){ if(newValue > 2004){ this._year = newValue; this.edition += newValue – 2004; } } }); book.year = 2005; alert(book.edition); //2
Définissez plusieurs propriétés : Object.defineProperties(), qui reçoit deux objets. L'une est la propriété à modifier ou à ajouter. Les propriétés du deuxième objet correspondent une à une aux propriétés du premier objet à modifier. ou ajoutés Navigateurs pris en charge : IE9+, FireFox4+, Safari5+, Opera12+, chrome
.
Lire les attributs : Object.getOwnPropertyDescriptor(), reçoit deux paramètres, l'objet où se trouve l'attribut et le nom de l'attribut du descripteur à lire. Navigateurs pris en charge : IE9+, FireFox4+, Safari5+, Opera12+, chrome
.
Créer un objet :
Mode usine :
function createPerson(name,age){ var o = new Object(); o.name = name; o.age = age; o.sayName = function(){ alert(this.name); }; return o; } var person1 = createPerson(“g”,29);
Modèle de constructeur :
function Person(name,age){ this.name = name; this.age = age; this.sayName() = function(){ alert(this.name); }; } var person = new Person(“g”,28);
La différence entre les deux modes :
En mode constructeur, il n'est pas nécessaire de créer explicitement l'objet, de lui attribuer directement une valeur et il n'y a pas d'instruction de retour
La première lettre du nom du constructeur doit être en majuscule et l'opérateur new doit être utilisé pour créer une nouvelle instance
Mode Prototype
Chaque fonction créée possède un attribut prototype, qui est un pointeur vers un objet. Le but de cet objet est de contenir des propriétés et des méthodes pouvant être partagées par toutes les instances d'un type spécifique. objet prototype de l'objet créé par la fonction. L'avantage est que toutes les instances peuvent partager les mêmes propriétés et méthodes.
isPrototypeOf(), ma compréhension personnelle est qu'il peut être utilisé pour déterminer si le prototype d'une instance est le même que le prototype actuel
Exemple :
Person.prototype.isPrototypeOf(person1); //true
Object.getPrototypeOf(), peut renvoyer le prototype d'une certaine instance, navigateurs pris en charge IE9+, Firefox3.5+, Safari5+, Opera12+, chrome
Remarque : lors de l'accès au nom de l'attribut de l'objet, une recherche sera effectuée. Tout d'abord, recherchez dans l'objet d'instance. S'il n'existe pas, recherchez dans l'objet prototype de l'objet actuel.
Remarque : Si les attributs de l'instance sont les mêmes que les attributs de l'objet prototype, les attributs de l'objet prototype seront bloqués, ce qui est exactement le même que le précédent
La méthode hasOwnProperty() peut déterminer si une propriété provient d'une instance. Si elle ne provient pas d'une instance, elle renvoie false, sinon elle renvoie true
Lorsque vous appelez delete sur une instance, seuls les noms d'attributs sur l'instance seront supprimés, et les attributs du prototype ne seront pas supprimés
Exemple :
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.sayName = function(){ alert(this.name); } var per1 = new Person(); var per2 = new Person(); per1.name = "Greg"; alert(per1.name); //"Greg" 来自实例 alert(per2.name); //"Nicholas" delete per1.name; alert(per1.name); //"Nicholas" 来自原型 delete per1.name; alert(per1.name); //"Nicholas"
Remarque : La méthode Object.getOwnPropertyDescriptor() ne peut être utilisée que pour les propriétés d'instance. Pour obtenir le descripteur de propriété du prototype, cette méthode doit être appelée directement sur l'objet prototype
Opérateur in : renvoie vrai uniquement si l'attribut est dans l'objet instance ou dans l'objet prototype
Exemple :
alert(“name” in Person); //true alert(“name” in per1); //true
Utiliser in et hasOwnProperty en même temps pour déterminer si la propriété existe dans le prototype ou l'instance
Méthode Object.keys() : reçoit un objet en paramètre et renvoie un tableau de chaînes composé de toutes les propriétés énumérables
Méthode Object.getOwnPropertyNames() : reçoit un objet et renvoie un tableau de chaînes composé de toutes les propriétés, qu'elles soient énumérables ou non
Syntaxe du prototype plus simple :
Il est trop compliqué d'utiliser la méthode ci-dessus. La méthode suivante est plus couramment utilisée : utiliser des littéraux d'objet
Person.prototype = { name : “Nicholas”, age : 29 sayName = function(){ alert(this.name); } }
Cependant, cette méthode équivaut à réécrire l'intégralité de l'objet prototype, ce qui fera que la propriété du constructeur ne pointera plus vers Personne mais vers Objet. Bien que instanceof renvoie toujours le résultat correct, le type d'objet ne peut pas être déterminé via le constructeur. .
var per = new Person(); alert(per instanceof Object); //true alert(per instanceof Person); //true alert(per constructor Object); //true alert(per constructor Person); //false
若constructor真的很重要,可以如下设置
Person.prototype = { constructor:Person, name : “Nicholas”, age : 29 sayName = function(){ alert(this.name); } }
以上写法会使constructor的enumerable特性被设置为true,默认情况下原生的是false的,在兼容ECMAScript5的浏览器可以使用Object.defineProperty()进行设置
Object.defineProperty(Person.prototype,”constructor”,{ enumerable:false, value:Person });
注:重写原型对象,将会切断现有原型与任何之前已经存在的对象实例之间的联系
继承(难度较大,需再仔细研究)
使用原型链来实现
子类型要覆盖超类的方法,应该将给原型添加方法的代码放在替换原型之后,
注:通过原型链实现继承时,不能使用对象字面量创建原型方法,否则会重写原型链
借用构造函数
组合继承
原型式继承,Object.creat();接收两个参数:一是用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象
例:Object.creat(person,{name:{value:”greg”}});
寄生式继承
寄生组合式继承
第7章,函数表达式
创建方式:
1、函数声明,可以函数声明提升,就是可以把使用函数的语句放在函数声明之前
function funName(arg0,arg1){ //函数体 }
2、函数表达式,不能进行函数提升,也就是无法在函数创建前使用函数,在这种情况下创建的函数称为匿名函数,有时也叫拉姆达函数
var funName = function(arg0,arg1){ //函数体 }
严格模式下无法使用arguments.callee来实现递归,可以使用如下方式实现递归:
var factorial = (function f(num){ if(num <= 1){ return 1; }else{ return num * f(num - 1); } });
闭包(难度也不小)
闭包指有权访问另一个函数作用域中的变量的函数,闭包,也是一个函数
创建闭包的常见方式是在一个函数内部创建另一个函数
闭包只能取得包含函数即外部函数中任何变量的最后一个值。下例可以清晰说明问题
例:
function createFuncrions(){ var result = new Array(); for(var i = 0;i < 10;i++){ result[i] = function(){ return i; } } return result; } var re = createFuncrions(); alert(re[1](2));
每个函数返回的都将是10,而不是如预期般返回对应的索引值,因为createFuncrions函数最后返回时I = 10,此时每个函数都引用保存着变量i的同一个对象,所以在每个函数内部i都是10,可以使用如下方法强制闭包返回预期效果:
function createFuncrions(){ var result = new Array(); for(var i = 0;i < 10;i++){ result[i] = function(num){ return function(){ return num; }; }(i); } return result; } var re = createFuncrions(); alert(re[2]());
每一个都会返回各自的索引值
模仿块级作用域
使用匿名函数可以模仿块级作用域:
(function(){ alert("test"); //块级作用域,没有使用圆括号将function包起来将会出错 })();
使用闭包和私有变量的明显不足之处在于,会在作用域链中多查找一个层次,在一定程度上影响查找速度
函数中定义的变量可以在一定程度上称为私有变量,通过函数可以模拟出私有变量,静态私有变量
增强模块模式:
var singleton = function(){ //private arg and private method var privateVariable = 10; function privateFunction(){ return false; } //create obj var obj = new Object(); obj.publicProperty = true; obj.publicFunction = function(){ privateVariable ++; return privateFunction(); }; return obj; }(); alert(typeof singleton); alert(singleton.publicProperty); alert(singleton.publicFunction());
以上内容是小编给大家介绍的JavaScript高级程序设计(第三版)学习笔记6、7章,希望对大家有所帮助!