1衷畦、原型
new的特性
1.創(chuàng)建一個對象
2.new執(zhí)行函數(shù)內(nèi)部的this指向這個new創(chuàng)建的對象
3.new執(zhí)行的本次函數(shù)結(jié)束時,默認返回這個new創(chuàng)建的對象
function fun(){
};
// 這是一個原型摇锋,原型也是一個對象丹拯,所有他有對應(yīng)的類的原型
// _proto_上面
// obj.__proto__ === fun.prototype
fun.prototype = { // 為了給實例提供公有的屬性
constructor : fun
}
const obj = new fun(); // 就是類的實例化,obj就是fun類的實例
- 判斷一個屬性是否是原型上的荸恕,
判斷方法:hasOwnProperty
私有屬性返回true乖酬,在原型上的返回false -
instanceof
用于確定obj1是上是否存在于obj2的原型鏈上
function fun(){
this.name = arguments[0]; // 這個名字是不定餐的第一個參數(shù)
}
fun.prototype = {
constructor: fun,
age: 18
}
const obj = new fun("hr");
console.log(obj.hasOwnProperty("name")); // 私有屬性 true
console.log(obj.hasOwnProperty("age")); // 公有 false
function fun1(){}
console.log(obj instanceof fun1); // false
// es5
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype = {
add(value){console.log(value)}
}
const obj = new Person("hr", 18);
// es6
class Person{
constructor(name, age){ // 就是對象,私有屬性
this.name = name;
this.age = age;
}
// 這之間不要加任何的符號
// constructor之外的方法都是公有
add(value){cosole.log(value)}
}
const obj = new Person("hr", 18);
2戚炫、原型繼承
繼承就是兒子要有父親的剑刑,兒子必須有父親的公有和私有屬性
// 父類,基類(模板)
function p1(opt){
this.money = opt.money;
this.house = opt.house;
}
p1.prototype.add = function(){
console.log(this.name);
}
// 子類双肤,繼承父類
function p2(opt){
p1.call(this,opt); // 繼承父類/基類的私有
this.car = opt.car;
}
p2.prototype.add = function (){
console.log(this.house);
}
// 第一種方案(子類繼承會破壞基類的地址施掏,不可取)
// p2.prototype = p1.prototype; // 這個是一個對象茅糜,是一個引用數(shù)據(jù)類型
// 第二種方案(__prototype__里面會顯示undefined)
// p2.prototype = new p1({});
// 第三種方案(__prototype__里面無undefined)
// function middle(){};
// middle.prototype = p1.prototype;
// p2.prototype = new middle();
// 第四種方案(不能繼承原型鏈上的屬性七芭,只能取到p1父類/基類上的屬性)
for(var key in p1.prototype){
p2.prototype[key] = p1.prototype[key];
}
const op1 = new p1({ // 把基類這個對象存到p2的原型上
money: "2億",
house: "海景別墅十套",
})
const op2 = new p2({ // 我們不需要一個個傳,可以傳遞一個對象的方式
money: "1億",
house: "海景別墅五套",
marry: "富婆"
})
op1.add(); // undefined
console.log(op2);
3蔑赘、對象的拷貝
原型的繼承也就是對象的繼承狸驳,其實也是對象的拷貝
對象的拷貝:
- 淺拷貝:新對象跟原對象內(nèi)容相同预明,指向同一個地址,新對象改變耙箍,原對象也會改變
- 深拷貝:新對象跟原對象內(nèi)容相同撰糠,但不指向同一個地址,新對象改變辩昆,原對象不會改變
-
深淺拷貝方法(支持拷貝函數(shù))
const obj1 = {
a: 1,
b: ["a", "b"]
};
// 深淺拷貝方法(支持拷貝函數(shù))
function extend(obj, deep){
// deep: false淺拷貝 true深拷貝
var curObj = {};
// 判定對象是數(shù)組
if (obj instanceof Array){
curObj = [];
}
for(var key in obj){
var value = obj[key]
// 判斷value是否是引用類型阅酪,并且當前是深淺拷貝
curObj[key] = (!!deep && typeof value === "object" && value !== null) ?
extend(value, deep) : value;
// deep是true則為深拷貝,false是淺拷貝汁针;兩次取反deep是為了把deep轉(zhuǎn)為布爾值
// 深拷貝术辐,則要對引用類型繼續(xù)深拷貝
}
return curObj;
}
// 默認是情況是淺拷貝,所以不用寫
const obj2 = extend(obj1, true);
obj2.b.push("x");
console.log(obj1);
console.log(obj2);
-
深拷貝方法(不支持拷貝函數(shù))
const obj1 = {
a: 1,
b: ["a", {
c: ["h"]
}]
}
// 對象先轉(zhuǎn)json字符串施无,再轉(zhuǎn)為json對象
const obj2 = JSON.parse(JSON.stringify(obj1));
-
深拷貝方法(es6)
// 父類
class p1{
constructor(x){
this.x = x;
}
add(){
console.log(this);
}
}
class p2 extends p1{
constructor(x){
super(x); // 不寫這步辉词,子類沒有this
}
sum(){
console.log("hello");
}
}
const op1 = new p1("0");
const op2 = new p2("1");
op1.add(); // {x: "0"}
op2.add(); // {x: "1"}
// op1.sum(); // 父類不會有子類自己的方法
op2.sum(); // hello
4、靜態(tài)屬性和方法
只能被類調(diào)用的屬性和方法
// es5 靜態(tài)屬性猾骡、方法
// 這是一個類
function myClass(){}
myClass.daying = function (){
console.log("這是一個靜態(tài)方法");
}
const obj = new myClass(); // 實例
// es6 只有靜態(tài)方法
class myClass1{
constructor(){}
static dayjing(){} // 只能是靜態(tài)方法
}