js學習筆記02-類和對象,繼承
//1)構造函數定義類,不用new function Dog(){ this.name = "Luby"; this.say = function(){ console.log("wangwang!"); } } let objDog = new Dog(); //創建對象的時候new //2)工廠方式定義類 function Dog(){ let dog = new Object; //變量,然後new Object; dog.name = "Luby"; dog.say = function(){ console.log("wangwang"); } return dog; } let dog = Dog(); //直接使用函數 //以上兩種方式的缺點:每一個新的對象都需要創建一個say(); //3)一般用原型+構造函數的方式定義類 function Dog(){ this.name = "Luby"; } Dog.prototype.say = function(){ console.log("wangwang!"); } let objDog = new Dog(); //
構造函數
結構語法
//構造函數並不聲明局部變量,而是使用 this 關鍵字來保存數據
//this 是指在構造函數前面使用 new 關鍵字創建的新對象
function SoftwareDeveloper() {
this.useLanguage = ‘JavaScript‘;
}
let developer = new SoftwareDeveloper();
查看對象的構造函數 (instanceof)
function SoftwareDeveloper() { this.useLanguage = ‘JavaScript‘; } let developer = new SoftwareDeveloper(); developer instanceof SoftwareDeveloper; // instanceof返回值為true;
constructor 屬性
每次創建一個對象時,都會有一個特殊的屬性被暗中分配給它:constructor。訪問一個對象的 constructor 屬性會返回一個對創建該對象的構造函數的引用!
function Cat(){
this.name = "fish";
}
let obj = new Cat();
console.log(obj.constructor); // ? Cat(){this.name = "fish";)
如果某個對象是使用字面量表示法創建的,那麽它的構造函數就是內置的 Object() 構造函數!
let obj = { name: "fish" } console.log(obj.constructor);// ? Object() { [native code] } // 和java的class一樣(每個class都有一個無參的什麽都不做得構造函數)
this
當使用 new 運算符來調用構造函數時,this 變量會被設置為新創建的對象。當在對象上調用方法時,this 會被設置為該對象本身。當在瀏覽器環境中調用函數時,this 會被設置為 window,也被稱為全局對象。
總結:
函數如何調用決定了函數內this的值(當前的函數屬於誰或當前發生事件的對象)
構造函數中的this 是指在構造函數前面使用 new 關鍵字創建的新對象
this的應用: call(),apply(),bind()(回調函數)
call() 是一個直接調用到函數上的方法。我們傳遞給它一個單一的值,以設置為 this 的值,然後逐個傳入該函數的任何參數,用逗號分隔。
apply()區別就是後面的多個參數為數組,事先並不知道函數所需要的參數個數就使用apply
const num = {
sum: function (n1,n2) {
return n1*n2;
}
};
const title = {
n1: 25,
n2: 18.0
}
console.log(num.sum.call(title,title.n1,title.n2));//450 相當於把.call前面的方法聲明到obj這個對象裏面
console.log(num.sum.apply(title,[title.n1,title.n2]));
使用 bind() 來保存 this(回調函數中的this)
const dog = {
age: 3,
growOneYear: function(){
this.age +=1;
}
}
function invokeTwice(cb) {
cb();
cb();
}
invokeTwice(dog.growOneYear);//這裏的this為window
console.log(dog.age); //3
let change = dog.growOneYear.bind(dog);
invokeTwice(change); //由bind指定了this為dog
console.log(dog.age); //5
window 對象
頁面的 URL (window.location;)
頁面的垂直滾動位置 (window.scrollY)
滾動到新位置(window.scroll(0, window.scrollY + 200);,從當前位置向下滾動 200 個像素)
打開一個新的網頁 (window.open("https://www.sugarbeans.com/");)
對象 Object
var goods = new Object();
Object.keys(goods);
Object.values(goods);
原型繼承prototype
JavaScript 中的繼承是指一個對象基於另一個對象
JavaScript 中的繼承重點就是建立原型鏈
當使用 new 運算符將一個函數作為構造函數來調用時,該函數會創建並返回一個新的對象。這個對象會被秘密鏈接到其構造函數的 prototype,而它只是另一個對象。使用這個秘密鏈接,可以讓一個對象訪問原型的屬性和方法,就像是它自己的一樣。如果 JavaScript 沒有在某個對象中找到一個特定屬性,它將在原型鏈上繼續查找。如有必要,它會一路查找到 Object()(頂級父對象)
proto(註意每一端有兩個下劃線)是構造函數所創建的所有對象(即實例)的一個屬性,並直接指向該構造函數的 prototype 對象(警告:不要使用這個屬性)
簡單應用
function Cat(){
this.name = "coff";
}
let cat1 = new Cat();
let cat2 = new Cat();
Cat.prototype.say = function(){
console.log("woool");
};
Cat.prototype.color = "red" //添加屬性
Cat.prototype = { //指向了新的對象
color: "red"
};
console.log(cat1.__proto__); // {say: ?, color: "red", constructor: ?}
Object.create()
防止子對象修改父對象的屬性 如:child.prototype.earBones = 5;
Object.create() 會接受一個對象作為參數,並返回一個新的對象,其 proto 屬性會被設置為傳遞給它的參數。然後,你只需要將所返回的對象設置為子對象構造函數的原型即可
const mammal = {
vertebrate: true,
earBones: 3
};
const rabbit = Object.create(mammal); //Object.create()
console.log(rabbit); // {}
console.log(rabbit.__proto__ === mammal); //true
構造函數之間的繼承
function Animal(name){
this.name = name;
}
Animal.prototype.walk = function(){
console.log(`${this.name} walks!`);
} //定義了類Animal
function Cat(name){
Animal.apply(this,[name]); //不使用new,使用父類的屬性,如下:
//let obj = new Animal(name);
// this.name = obj.name;
}
Cat.prototype = Object.create(Animal.prototype); //類Cat繼承Animal
let str = new Cat("miaomiao");
console.log(str.walk());
原型相關的函數
hasOwnProperty
hasOwnProperty() 可以幫助你找到某個特定屬性的來源。在向其傳入你要查找的屬性名稱的字符串後,該方法會返回一個布爾值,指示該屬性是否屬於該對象本身(即該屬性不是被繼承的)
function Phone() {
this.operatingSystem = ‘Android‘;
}
Phone.prototype.screenSize = 6;
const myPhone = new Phone();
const own = myPhone.hasOwnProperty(‘operatingSystem‘); // true
const inherited = myPhone.hasOwnProperty(‘screenSize‘); // false
isPrototypeOf()和Object.getPrototypeOf()
isPrototypeOf()可以檢查某個對象是否存在於另一個對象的原型鏈中。
Object.getPrototypeOf()確定某個對象的原型是什麽呢
const dog = {
name: "hero",
age: 2
}
function Cat(){
this.say= function(){
console.log("miaomiao")
};
};
Cat.prototype = dog; //
let str = new Cat();
//str.say();方法已經被覆蓋
dog.isPrototypeOf(str); //true 註意調用順序.
const myPrototype = Object.getPrototypeOf(str); //獲取原型
console.log(myPrototype); //{name: "hero", age: 2}
js學習筆記02-類和對象,繼承