Kapitel 6, Objektorientierte Programmierung
Objekt:
1. Datenattribute
konfigurierbar und gibt an, ob das Attribut durch Löschen des Attributs neu definiert werden kann, ob die Eigenschaften des Attributs geändert werden können oder ob das Attribut in ein Accessor-Attribut geändert werden kann. Der Standardwert ist true
Aufzählung, die angibt, ob über for-in auf das Attribut zugegriffen werden kann, der Standardwert ist true
beschreibbar, gibt an, ob der Attributwert geändert werden kann, der Standardwert ist true
Wert, Datenspeicherort, Standard ist undefiniert
Ändern Sie die Standardattributeigenschaften: Object.defineProperty(), das drei Parameter empfängt: das Objekt, in dem sich das Attribut befindet, den Attributnamen und das Deskriptorobjekt. Die Attribute des Deskriptorobjekts müssen konfigurierbar, aufzählbar, beschreibbar sein. Wert
Beispiel:
var obj = {}; Object.defineProperty(obj,”name”,{ writable:true, value:”nihao” });
2. Accessor-Eigenschaften
konfigurierbar und gibt an, ob das Attribut durch Löschen des Attributs neu definiert werden kann, ob die Eigenschaften des Attributs geändert werden können oder ob das Attribut in ein Accessor-Attribut geändert werden kann. Der Standardwert ist true
Aufzählung, die angibt, ob über for-in auf das Attribut zugegriffen werden kann, der Standardwert ist true
get, wird beim Lesen von Attributen aufgerufen, der Standardwert ist undefiniert
set, wird beim Schreiben von Attributen aufgerufen, der Standardwert ist undefiniert
Die Änderung muss über Object.defineProperty() erfolgen
Beispiel:
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
Definieren Sie mehrere Eigenschaften: Object.defineProperties(), das zwei Objekte empfängt. Eines ist die Eigenschaft, die geändert oder hinzugefügt werden soll. Die Eigenschaften des zweiten Objekts entsprechen eins zu eins den Eigenschaften des ersten zu ändernden Objekts oder unterstützte Browser: IE9+, FireFox4+, Safari5+, Opera12+, Chrome
Attribute lesen: Object.getOwnPropertyDescriptor(), empfängt zwei Parameter, das Objekt, in dem sich das Attribut befindet, und den Attributnamen des zu lesenden Deskriptors: IE9+, FireFox4+, Safari5+, Opera12+, Chrome
Objekt erstellen:
Werksmodus:
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);
Konstruktormuster:
function Person(name,age){ this.name = name; this.age = age; this.sayName() = function(){ alert(this.name); }; } var person = new Person(“g”,28);
Der Unterschied zwischen den beiden Modi:
Im Konstruktormodus besteht keine Notwendigkeit, das Objekt explizit zu erstellen, diesem direkt einen Wert zuzuweisen, und es gibt keine Return-Anweisung
Der erste Buchstabe des Konstruktornamens muss großgeschrieben werden und der neue Operator muss zum Erstellen einer neuen Instanz verwendet werden
Prototyp-Modus
Jede erstellte Funktion verfügt über ein Prototypattribut, das einen Zeiger auf ein Objekt darstellt. Der Zweck dieses Objekts besteht darin, Eigenschaften und Methoden zu enthalten, die von allen Instanzen eines bestimmten Typs gemeinsam genutzt werden können Prototypobjekt des von der Funktion erstellten Objekts. Der Vorteil besteht darin, dass alle Instanzen dieselben Eigenschaften und Methoden verwenden können.
isPrototypeOf(), mein persönliches Verständnis ist, dass es verwendet werden kann, um festzustellen, ob der Prototyp einer Instanz mit dem aktuellen Prototyp identisch ist
Beispiel:
Person.prototype.isPrototypeOf(person1); //true
Object.getPrototypeOf(), kann den Prototyp einer bestimmten Instanz zurückgeben, unterstützte Browser IE9+, Firefox3.5+, Safari5+, Opera12+, Chrome
Hinweis: Beim Zugriff auf den Objektattributnamen wird zunächst im Instanzobjekt gesucht. Wenn es nicht vorhanden ist, wird im Prototypobjekt des aktuellen Objekts gesucht.
Hinweis: Wenn die Attribute in der Instanz mit den Attributen im Prototypobjekt identisch sind, werden die Attribute des Prototypobjekts blockiert, was genau die gleichen sind wie beim vorherigen
Die Methode hasOwnProperty() kann ermitteln, ob eine Eigenschaft von einer Instanz stammt. Wenn sie nicht von einer Instanz stammt, gibt sie „false“ zurück, andernfalls gibt sie „true“ zurück
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"
alert(“name” in Person); //true alert(“name” in per1); //true
Einfachere Prototyp-Syntax:
Person.prototype = { name : “Nicholas”, age : 29 sayName = function(){ alert(this.name); } }
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章,希望对大家有所帮助!