JavaScript 中的萬物皆對象:字符串、數值、數組、函數...
對象只是帶有屬性和方法的特殊數據類型:
Oobject類型的創建方法
??????1.使用new運算符
var obj = new Object(); // 或者省略new var obj = Object();
obj.name = "張三";
obj.age = 18;
??????2.使用字面量方式創建,鍵值對方式:k: v
var obj0 = {
name: "張三",
age: 18
};
// 或者屬性字段用字符串形式:
obj1 = {
"name": "張三",
"age": 18
};
// 也可以用傳統的賦值方式:
var obj2 = {};
obj2.name = " 張三";
obj2.age = 18;
??????3.給對象創建方法
var obj = {
run: function() {
return '正在奔跑';
}
}
構造函數
構造函數:通常使用構造函數代表類
function Animal(name, age) {
this.name = name; // this指的是使用new關鍵字,調用Animal所創建的對象
this.age = age;
this.show = function() {
console.log(this.name + ',' + this.age);
};
};
var animal1 = new Animal('熊貓', 2);
var animal2 = new Animal('東北虎', 3);
animal1.show(); // 熊貓, 2
animal2.show(); // 東北虎, 3
image.png
其實在js中并沒有類的概念,但是通常我們認為構造函數就是類。
上面的Animal就是類,animal1和animal2是對象,也是Animal的實例
類是對象的抽象
對象是類的具體
注意
- 在Animal使用new關鍵字創建的過程中,內部會自動創建一個對象;
- 然后把this這個指針指向創建的這個對象;
- 執行完代碼后,還會返回這個對象;
原型對象
prototype:原型
function Box() { // 構造函數
};
Box.prototype.name = "虞姬";
Box.prototype.age = "18";
Box.prototype.show = function() {
console.log(this.name + ',' + this.age);
};
var box = new Box(); // 實例
console.log(box.name); // 虞姬
console.log(box.age); // 18
console.log(box.show); // 虞姬, 18
- constructor: 原型對象prototype的屬性,指向當前原型所屬的構造函數,即:
console.log(Box.prototype.constructor === Box); // true
image.png
- _ _ proto _ _屬性:實例對象指向原型對象的一個指針,它的作用是指向構造函數的原型,即
console.log(box.__proto__ === Box.prototype); // true
console.log(box.__proto__.name); // 虞姬
image.png
- isPrototype(): 用來判斷某個對象是否指向該原型對象的構造函數
?1.查找實例對象是否存在該屬性,如果存在則返回該屬性的值;
?2.如果不存在,則查找原型對象中是否存在,若存在,則返回該屬性的值;
?3.如果都不存在,則返回underfine。
console.log(Box.prototype.isPrototype(box)); // true
console.log(Box.prototype.isPrototype(box1)); // underfine
- hasOwnPrototype(): 用來判斷該實例對象中是否含有該屬性
?1.存在,則返回true;
?2.不存在,則返回false;
console.log(box.hasOwnPrototype(name)); // true
console.log(box.hasOwnPrototype(type)); // false
- in操作符:用于判斷屬性是否存在實例對象或者原型對象
?首先會先判斷當前實例對象中是否存在該屬性,若存在,則返回true;若不存在,則會繼續在原型對象中查找該屬性,若存在,則返回true;若不存在,則繼續往原型鏈的頂端Object.prototype中找,如果都沒有就會返回false。
console.log("name" in box); // true
console.log("type" in box); // false
-
原型鏈
?所有的函數對象都繼承自原始函數對象;Function比較特殊,他的原型對象也就是原始函數對象;所以我們往往用Function.prototype表示原始函數對象;而原始函數對象又繼承自原始對象。
image.png - 封裝:把部分屬性和方法封裝起來,不提供給外界使用
// 工廠模式創建
function createObject(_name, _age) {
var obj = new Object(); // 創建對象
obj.name = _name;
obj.age = _age;
obj.show = function() {
console.log(this.name + ',' + this.age);
};
return obj;
}
var person1 = createObject('Jacky', 18);
var person2 = createObject('喵喵', 20);
person1.show(); // Jacky, 18
person2.show(); // 喵喵,20
- 繼承:可以把原有對象(父類)的屬性和方法,復制給一個新的對象,新的對象還可以擁有自己的屬性和方法
?1.原型鏈繼承
?2.對象冒充,call和apply繼承
???????對象.call(新this對象,實參1,實參2,實參3.....)
???????對象.apply(新this對象,[實參1,實參2,實參3.....])
function Cat() { // 父類
this.fur = "有軟毛";
this.eat = function() {
console.log("喜歡吃魚");
};
this.call = function() {
console.log("喵~");
}
};
function GarfriendCat() {
this.galssess = "戴墨鏡"; // 新增自己的屬性
this.talk = function() { // 新增自己的方法
console,log("會說話");
};
this.eat = function() { // 重寫父類的eat方法
console.log("只吃肉!");
}
};
GarfriendCat.prototype = new Cat(); // 使用原型鏈來實現繼承。
// 對象冒充: 借用構造函數Cat,用this冒充Cat
function Person(_name, _age) {
this.name = _name;
this.age = _age;
}
// call
function CallCopy(_name, _age, _gender) {
Person.call(this, _name, _age);
this.gender = _gender;
} ;
var callCopy = new CallCopy('Jacky', 18, '男');
console.log(callCopy.name, callCopy.age, callCopy.gender); // Jacky 18 男
// apply
function ApplyCopy(_name, _age, _gender) {
Person.apply(this, [_name, _age]);
this.gender = _gender;
} ;
var applyCopy = new ApplyCopy('Lusi', 20, '女');
console.log(applyCopy.name, applyCopy.age, applyCopy.gender); // Lusi 20 女
- 多態:基于繼承,父類可以指向不同的子類,父類調用同一個方法時,不同的子類執行的效果不一樣。
function beGoodAt(animal) {
animal.show();
};
var Monkey = function() {};
Monkey.prototype.show = function() {
console.log('猴子擅長于爬樹');
}
var Cheetah = function() {}
Cheetah.prototype.show = function() {
console.log('獵豹擅長于奔跑');
}
beGoodAt(new Monkey()); // 猴子擅長于爬樹
beGoodAt(new Cheetah()); // 獵豹擅長于奔跑