一
/*
1.在ES6以前若是定義一個類?
經過構造函數來定義一個類
*/
function Person(myName, myAge) { // 實例屬性 // this.name = "lnj"; // this.age = 34; this.name = myName; this.age = myAge; // 實例方法 this.say = function () { console.log(this.name, this.age); } // 靜態屬性 Person.num = 666; // 靜態方法 Person.run = function () { console.log("run"); } } // let p = new Person(); let p = new Person("zs", 18); p.say(); console.log(Person.num); Person.run();
/*
2.從ES6開始系統提供了一個名稱叫作class的關鍵字, 這個關鍵字就是專門用於定義類的
*/
class Person{ // 當咱們經過new建立對象的時候, 系統會自動調用constructor // constructor咱們稱之爲構造函數 constructor(myName, myAge){ this.name = myName; this.age = myAge; } // 實例屬性 // name = "lnj"; // age = 34; // 實例方法 say(){ console.log(this.name, this.age); } // 靜態屬性 static num = 666; // 靜態方法 static run() { console.log("run"); } } // let p = new Person(); let p = new Person("zs", 18); p.say(); console.log(Person.num); Person.run();
須要注意的地方:瀏覽器
1 app
class Person{ // 如下定義"實例屬性"的方式並非ES6正式版標準中的寫法, 大部分的瀏覽器不支持 // 在ES6標準中添加實例屬性都須要在constructor中添加 // 實例屬性 // name = "lnj"; // age = 34; constructor(){ this.name = "lnj"; this.age = 34; } // 實例方法 say(){ console.log(this.name, this.age); } } let p = new Person(); console.log(p);
2 函數
class Person{ // 如下定義"靜態屬性"的方式並非ES6正式版標準中的寫法, 大部分的瀏覽器不支持 // 在ES標準中static只支持定義靜態方法不支持定義靜態變量 // 靜態屬性 // static num = 666; // 靜態方法 static run() { console.log("run"); } } Person.num = 666; let p = new Person(); console.log(p);
二this
function Person(myName, myAge) { // 實例屬性 this.name = myName; this.age = myAge; // 實例方法 this.hi = function () { console.log("hi"); } } // 原型上的方法 Person.prototype.say = function () { console.log(this.name, this.age); } let p = new Person("lnj", 34); console.log(p); class Person{ constructor(myName, myAge){ this.name = myName; this.age = myAge; //構造函數裏面添加的方法會添加到 對象自己 this.hi = function () { console.log("hi"); } } //在類裏面添加的方法會加到原型對象中 say(){ console.log("hi"); } } let p = new Person("lnj", 34); console.log(p);
四spa
注意點:
若是經過class定義類, 那麼不能自定義這個類的原型對象
若是想將屬性和方法保存到原型中, 只能動態給原型對象添加屬性和方法
function Person(myName, myAge) { // 實例屬性 this.name = myName; this.age = myAge; // 實例方法 this.hi = function () { console.log("hi"); } } // 原型上的方法 // Person.prototype.type = "人"; // Person.prototype.say = function () { // console.log(this.name, this.age); // }; //function方式定義的構造函數能夠修改 原型對象 Person.prototype = { constructor: Person, type: "人", say: function () { console.log(this.name, this.age); } }; class Person{ constructor(myName, myAge){ this.name = myName; this.age = myAge; this.hi = function () { console.log("hi"); } } run(){ console.log("run"); } } // Person.prototype.type = "人"; // Person.prototype.say = function () { // console.log(this.name, this.age); // }; let obj = { constructor: Person, type: "人", say: function () { console.log(this.name, this.age); } }; //修改對象原型無效 Person.prototype = obj; let p = new Person("lnj", 34); console.log(p);
五 繼承prototype
ES6以前的繼承
1.在子類中經過call/apply方法藉助父類的構造函數
2.將子類的原型對象設置爲父類的實例對象
function Person(myName, myAge) { this.name = myName; this.age = myAge; } Person.prototype.say = function () { console.log(this.name, this.age); } function Student(myName, myAge, myScore) { // 1.在子類中經過call/apply方法藉助父類的構造函數 Person.call(this, myName, myAge); this.score = myScore; this.study = function () { console.log("day day up"); } } // 2.將子類的原型對象設置爲父類的實例對象 Student.prototype = new Person(); Student.prototype.constructor = Student; let stu = new Student("zs", 18, 99); stu.say();
1.在ES6中如何繼承
1.1在子類後面添加extends並指定父類的名稱
1.2在子類的constructor構造函數中經過super方法藉助父類的構造函數
class Person{ constructor(myName, myAge){ // this = stu; this.name = myName; // stu.name = myName; this.age = myAge; // stu.age = myAge; } say(){ console.log(this.name, this.age); } } /* 1.在ES6中如何繼承 1.1在子類後面添加extends並指定父類的名稱 1.2在子類的constructor構造函數中經過super方法藉助父類的構造函數 */ // 如下代碼的含義: 告訴瀏覽器未來Student這個類須要繼承於Person這個類 class Student extends Person{ constructor(myName, myAge, myScore){ // 1.在子類中經過call/apply方法藉助父類的構造函數 // Person.call(this, myName, myAge); super(myName, myAge); this.score = myScore; } study(){ console.log("day day up"); } } let stu = new Student("zs", 18, 98); stu.say();
六 獲取對象類型code
let obj = new Object(); console.log(typeof obj); // object let arr = new Array(); /* * 這樣的打印會是object,這是由於 在全部構造函數中,內部其實會新建一個Object對象,而後賦值給this * */ console.log(typeof arr); // object console.log(arr.constructor.name); // Array function Person() { // let obj = new Object(); // let this = obj; this.name = "lnj"; this.age = 34; this.say = function () { console.log(this.name, this.age); } // return this; } let p = new Person(); // console.log(typeof p); // object console.log(p.constructor.name); // Person
七 instanceof 關鍵字對象
1.什麼是instanceof關鍵字?
instanceof用於判斷 "對象" 是不是指定構造函數的 "實例"
2.instanceof注意點blog
只要 構造函數的原型對象出如今實例對象的原型鏈中都會返回true
class Person{ name = "lnj"; } let p = new Person(); console.log(p instanceof Person); // true class Cat{ name = "mm"; } let c = new Cat(); console.log(c instanceof Person); // false function Person(myName) { this.name = myName; } function Student(myName, myScore) { Person.call(this, myName); this.score = myScore; } Student.prototype = new Person(); Student.prototype.constructor = Student; let stu = new Student(); /* * 返回true的緣由爲 Person的原型對象出如今了stu的原型鏈上 * */ console.log(stu instanceof Person); // true
八 isPrototypeOf繼承
1.什麼是isPrototypeOf屬性
isPrototypeOf用於判斷 一個對象是不是另外一個對象的原型
2.isPrototypeOf注意點
2.1只要調用者在傳入對象的原型鏈上都會返回true
class Person{ name = "lnj"; } let p = new Person(); console.log(Person.prototype.isPrototypeOf(p)); // true class Cat{ name = "mm"; } console.log(Cat.prototype.isPrototypeOf(p)); // false function Person(myName) { this.name = myName; } function Student(myName, myScore) { Person.call(this, myName); this.score = myScore; } Student.prototype = new Person(); Student.prototype.constructor = Student; let stu = new Student(); console.log(Person.prototype.isPrototypeOf(stu)); // true
八 判斷某一個對象是否擁有某一個屬性
// 需求: 判斷某一個對象是否擁有某一個屬性 class Person{ name = null; age = 0; } Person.prototype.height = 0; let p = new Person(); // in的特色: 只要類中或者原型對象中有, 就會返回true console.log("name" in p); // true console.log("width" in p); // false console.log("height" in p); // true // 需求: 判斷某一個對象自身是否擁有某一個屬性 let p = new Person(); // 特色: 只會去類中查找有沒有, 不會去原型對象中查找 console.log(p.hasOwnProperty("name")); // true console.log(p.hasOwnProperty("height")); // false
九 深拷貝和淺拷貝
1.什麼是深拷貝什麼是淺拷貝?
1.1深拷貝
修改新變量的值不會影響原有變量的值
默認狀況下基本數據類型都是深拷貝
1.1淺拷貝
修改新變量的值會影響原有的變量的值
默認狀況下引用類型都是淺拷貝
萬能深拷貝方法
class Person{ name = "lnj"; cat = { age : 3 }; scores = [1, 3, 5]; } let p1 = new Person(); let p2 = new Object(); /* // p2.name = p1.name; // p2.name = "zs"; // console.log(p1.name); // console.log(p2.name); p2.cat = p1.cat; p2.cat.age = 666; console.log(p1.cat.age); console.log(p2.cat.age); */ depCopy(p2, p1); // console.log(p2); p2.cat.age = 666; console.log(p1.cat.age); console.log(p2.cat.age); function depCopy(target, source) { // 1.經過遍歷拿到source中全部的屬性 for(let key in source){ // console.log(key); // 2.取出當前遍歷到的屬性對應的取值 let sourceValue = source[key]; // console.log(sourceValue); // 3.判斷當前的取值是不是引用數據類型 if(sourceValue instanceof Object){ // console.log(sourceValue.constructor); // console.log(new sourceValue.constructor); let subTarget = new sourceValue.constructor; target[key] = subTarget; depCopy(subTarget, sourceValue); }else{ target[key] = sourceValue; } } }