【創利樹】電商的使用者流失率是80%,你的使用者流失率是多少呢?
阿新 • • 發佈:2020-10-12
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 值型別(基本型別):字串(string)、數值(number)、布林值(boolean)、undefined、null// 引用型別:物件(Object)、陣列(Array)、函式(Function) /* 原型鏈 繼承 問題:1.包含引用型別值的原型屬性會被所有例項共享 陣列(引用型別值)。 2.在建立子型別的例項時,不能向超型別的建構函式中傳遞引數。 */ function SuperType() { this.property = true; // this.colors = ["red","black"]; } SuperType.prototype.colors = ["red", "black"]; SuperType.prototype.getSuperValue = function () { return this.property; }; function SubType() { this.subproperty = false; } //繼承了SuperType 原型鏈繼承 SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function () { return this.subproperty; };var instance1 = new SubType(); var instance2 = new SubType(); instance1.colors.push("green"); console.log(instance1.getSuperValue()); //true console.log(instance1.colors);//["red", "black", "green"] console.log(instance2.colors);//["red", "black", "green"] console.log(instance1);//SubType{subproperty: false} console.log(instance1.__proto__);//SuperType{property: true, getSubValue: ƒ} /* 借用建構函式 繼承 候也叫做 偽造物件 或 經典繼承 問題:方法都在建構函式中定義,因此函式複用就無從談起了 */ function SuperType2(name) { this.name = name; this.colors = ["red", "blue", "green"]; this.sayName = function () { console.log(this.name); } } function SubType2() { //繼承了SuperType 構造繼承 // this -> SubType // SuperType2.call(this); // 傳遞引數 SuperType2.call(this, "趙品霖"); } //繼承了SuperType // SubType.prototype = new SuperType(); var instance3 = new SubType2(); var instance4 = new SubType2(); instance3.colors.push("black"); console.log(instance3.colors); //["red", "blue", "green", "black"] console.log(instance4.colors); //["red", "blue", "green"] console.log(instance3.sayName == instance4.sayName); //false 函式無法複用 console.log(instance3);//SubType2{name: "趙品霖", colors: Array(4), sayName: ƒ} console.log(instance3.__proto__);//{constructor: ƒ} /* 組合繼承 思想:即在子型別建構函式的內部呼叫超型別建構函式 instanceof 和isPrototypeOf()也能夠用於識別基於組合繼承建立的物件。 問題:無論什麼情況下,都會呼叫兩次超型別建構函式:一次是在建立子型別原型的時候,另一次是在子型別建構函式內部。 解決方法 ——寄生組合式繼承。 */ function SuperType3(name) { this.name = name; this.colors = ["red", "blue", "green"]; } SuperType3.prototype.sayName = function () { console.log(this.name); } function SubType3(name, age) { //繼承屬性 構造繼承 SuperType3.call(this, name);////第二次呼叫SuperType() this.age = age; } //繼承方法 原鏈繼承 SubType3.prototype = new SuperType3();////第一次呼叫SuperType() SubType3.prototype.constructor = SubType3; SubType3.prototype.sayAge = function () { console.log(this.age); }; // 例項既分別擁有自己屬性——包括colors 屬性,又可以使用相同的方法了。 var instance5 = new SubType3("aa", 20); var instance6 = new SubType3("bb", 21); instance5.colors.push("black"); console.log(instance5.colors); //["red", "blue", "green", "black"] console.log(instance6.colors); //["red", "blue", "green"] instance5.sayName();//aa instance6.sayName();//bb console.log(instance5.sayName == instance6.sayName); //true console.log(instance5); //SubType3{name: "aa", colors: Array(4), age: 20} console.log(instance5.__proto__); //SuperType3{name: undefined, colors: Array(3), constructor: ƒ, sayAge: ƒ} /* 原型式繼承 藉助原型可以基於已有的物件建立新物件,同時還不必因此建立自定義型別 Object.create(person); 在沒有必要興師動眾地建立建構函式,而只想讓一個物件與另一個物件保持類似的情況下,原型式繼承是完全可以勝任的。 不過別忘了,包含引用型別值的屬性始終都會共享相應的值,就像使用原型模式一樣。 */ var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; // ECMAScript 5 通過新增Object.create()方法規範化了原型式繼承。 // 這個方法接收兩個引數:一個用作新物件原型的物件和(可選的); 一個為新物件定義額外屬性的物件 var anotherPerson = Object.create(person); // 重寫name anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); // var yetAnotherPerson = Object.create(person); // yetAnotherPerson.name = "Linda"; // Object.create() 接受第2個引數 var yetAnotherPerson = Object.create(person, { name: { value: "Linda" } }); yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); //["Shelby", "Court", "Van", "Rob", "Barbie"] /* 寄生式繼承: 寄生式繼承的思路與寄生建構函式和工廠模式類似. 即建立一個僅用於封裝繼承過程的函式,該函式在內部以某種方式來增強物件,最後再像真地是它做了所有工作一樣返回物件。 在主要考慮物件而不是自定義型別和建構函式的情況下,寄生式繼承也是一種有用的模式。前 */ function createAnother(original) { var clone = Object(original); //通過呼叫函式建立一個新物件 clone.sayHi = function () { //以某種方式來增強這個物件 console.log("hi"); }; return clone; //返回這個物件 } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi" /* 寄生組合式繼承 所謂寄生組合式繼承,即通過借用建構函式來繼承屬性,通過原型鏈的混成形式來繼承方法. 基本思路是:不必為了指定子型別的原型而呼叫超型別的建構函式,我們所需要的無非就是超型別原型的一個副本而已。 本質上,就是使用寄生式繼承來繼承超型別的原型,然後再將結果指定給子型別的原型。 它只調用了一次SuperType 建構函式,並且因此避免了在SubType.prototype 上面建立不必要的、多餘的屬性。 與此同時,原型鏈還能保持不變;因此,還能夠正常使用instanceof 和isPrototypeOf()。 開發人員普遍認為寄生組合式繼承是引用型別最理想的繼承正規化。 */ function inheritPrototype(subType, superType) { var prototype = Object(superType.prototype); //建立物件 寄生式繼承來繼承超型別的原型 // 彌補因重寫原型而失去的預設的constructor 屬性 prototype.constructor = subType; //增強物件 subType.prototype = prototype; //指定物件 將結果指定給子型別的原型。 } function SuperType4(name) { this.name = name; this.colors = ["red", "blue", "green"]; } SuperType4.prototype.sayName = function () { console.log(this.name); }; function SubType4(name, age) { SuperType4.call(this, name); this.age = age; } inheritPrototype(SubType4, SuperType4); SubType4.prototype.sayAge = function () { console.log(this.age); }; var instance7 = new SubType4("ee", 19); var instance8 = new SubType4("ff", 22); instance7.colors.push("black"); console.log(instance7.colors);//["red", "blue", "green", "black"] console.log(instance8.colors);//["red", "blue", "green"] console.log(instance7.sayName == instance8.sayName);//true console.log(instance7.sayAge == instance8.sayAge);//true </script> </body> </html>
寄生組合式繼承 示例: