JavaScript 精粹 基礎(chǔ) 進(jìn)階(8)OOP面向?qū)ο缶幊?上)

面向?qū)ο缶幊蹋琽op并不是針對(duì)與javascript,很多語(yǔ)言都實(shí)現(xiàn)了oop這樣一個(gè)編程發(fā)法論,比如說(shuō)java,c++,都是實(shí)現(xiàn)了oop的語(yǔ)言。

概念與繼承

概念

面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-oriented programming OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開發(fā)的方法。對(duì)象指的是類的實(shí)例,它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性,靈活性和擴(kuò)展性。 來(lái)自于 ----維基百科

OOP重點(diǎn)的一些特性:

  • 繼承

  • 封裝

  • 多態(tài)

  • 抽象

基于原型的繼承

function Foo() {
    this.y = 2;
};
Foo.prototype.x = 1;
console.log(Foo.prototype); //object
var obj1 = new Foo();
console.log(obj1.y); //2
console.log(obj1.x); //1

函數(shù)聲明創(chuàng)建Foo()函數(shù),這個(gè)函數(shù)就會(huì)有一個(gè)內(nèi)置的Foo.prototype,并且這個(gè)屬性是對(duì)象,并且是預(yù)設(shè)的。

function Foo() {
    this.y = 2;
};

console.log(Foo.prototype); //object
Paste_Image.png
function Foo() {
    this.y = 2;
};
Foo.prototype.x = 1;
console.log(Foo.prototype); //object
Paste_Image.png

然后我們把Foo.prototype對(duì)象增加一個(gè)屬性x并且賦值為1。

function Foo() {
    this.y = 2;
};
Foo.prototype.x = 1;
console.log(Foo.prototype); //object
var obj1 = new Foo();
console.log(obj1.y); //2
console.log(obj1.x); //1 

然后使用new操作符new Foo();來(lái)創(chuàng)建一個(gè)Foo();的實(shí)例,叫obj1,

當(dāng)時(shí)用new去調(diào)用函數(shù)的時(shí)候,那么構(gòu)造器也就是說(shuō)這樣一個(gè)函數(shù)就會(huì)作為一個(gè)構(gòu)造器來(lái)使用,并且this會(huì)指向一個(gè)對(duì)象,而對(duì)象的原型會(huì)指向構(gòu)造器的Foo.prototype屬性。obj1實(shí)際上會(huì)成為Foo構(gòu)造器中的this,最后會(huì)作為返回值,并且在構(gòu)造器里面調(diào)用的時(shí)候會(huì)把y賦值為2,并且obj1的原型,也就是他的proto會(huì)指向Foo.prototype內(nèi)置屬性,最后可以看到obj.y會(huì)返回2,obj.x會(huì)返回1,y是這個(gè)對(duì)象上的直接量,而x是原型鏈上的,也就是Foo.prototype的

function Foo() {
    this.y = 2;
};
Foo.prototype.x = 1;
console.log(Foo.prototype);
var obj1 = new Foo();

console.log(obj1);
Paste_Image.png

prototype屬性與原型

function Foo() {};
console.log(Foo.prototype);
Foo.prototype.x=1;
var obj=new Foo();
Paste_Image.png

使用函數(shù)聲明去中創(chuàng)建一個(gè)函數(shù)的時(shí)候,這個(gè)函數(shù)就會(huì)有一個(gè)prototype屬性,并且他默認(rèn)會(huì)有兩個(gè)屬性。

  • 一個(gè)是constructor:Fooconstructor屬性會(huì)指向它本身Foo。

  • 另外一個(gè)屬性是__proto____proto__Foo.prototype的原型,那么他的原型會(huì)指向Object.prototype也就是說(shuō)一般的對(duì)象比如用花括號(hào)括起來(lái)的對(duì)象字面量,他也會(huì)有__proto__他會(huì)指向Object.prototype因此Object.prototype上面的一些方法比如說(shuō)toStringvalueOf才會(huì)被每一個(gè)一般的對(duì)象所使用,

x:1這個(gè)是我通過(guò)賦值語(yǔ)句增加的。

**這句是Foo.prototype的結(jié)構(gòu) **

也就是說(shuō),這里面有一個(gè)Foo函數(shù),這個(gè)Foo函數(shù)呢會(huì)有一個(gè)prototype的對(duì)象屬性,他的作用呢就是在當(dāng)使用new Foo()去構(gòu)造Foo的實(shí)例的時(shí)候,那么構(gòu)造器的prototype的屬性,會(huì)用作new出來(lái)的這些對(duì)象的原型。

所以要搞清楚prototype和原型是兩回事。

prototype是函數(shù)對(duì)象上的預(yù)設(shè)的對(duì)象屬性,而原型呢是我們對(duì)象上的一個(gè)原型,原型通常都是他的構(gòu)造器的prototype屬性。

實(shí)現(xiàn)class繼承另外一個(gè)class

function Person(name, age) {
    this.name = name;
    this.age = age;
};

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.legs_num = 2;
Person.prototype.arms_num = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
};

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;


Student.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new,and form" + this.className + ".");
};

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};

console.log(Student.prototype);

var t = new Student("黃繼鵬", 23, "class2");
t.hi();
console.log(t.legs_num);
t.walk();
t.learn('math')

這里有一個(gè)函數(shù)Person,人的意思意思是說(shuō)只要人類的class。 在這個(gè)構(gòu)造函數(shù)里面,通過(guò)this.name = name;this.age = age;去做一個(gè)賦值,如何Person作為函數(shù)直接去調(diào)用的話,那么這里的this會(huì)指向全局對(duì)象,在瀏覽器里就會(huì)指向window,使用new去調(diào)用Person函數(shù)的時(shí)候,this會(huì)指向一個(gè)原型為Person.prototype的一個(gè)空對(duì)象,然后通過(guò)this.name去給這個(gè)空對(duì)象賦值,最后這里沒有寫返回值,使用new會(huì)this會(huì)作為返回值。

通過(guò)Person.prototype.hi來(lái)創(chuàng)建所有Person實(shí)例共享的方法。

再創(chuàng)建Student函數(shù),學(xué)生這樣一個(gè)class,那么學(xué)生是也是人,他是可以繼承人的,每一個(gè)學(xué)生也是人,并且學(xué)生會(huì)有他的班級(jí)名稱或者一些其他的功能方法,

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};

創(chuàng)建Student函數(shù),這里多傳了一個(gè)className參數(shù),在Student函數(shù)也算是子類里先調(diào)用下父類,Person.call(this, name, age);然后把this作為Person里面的this再把name和age傳進(jìn)去,注意這里的this在new被實(shí)例的時(shí)候會(huì)是這個(gè)實(shí)例的返回值也就是直接量,

this.className = className;并且把Student的實(shí)例做好賦值,

把Student.prototype能繼承Person.prototype的一些方法

Student.prototype = Object.create(Person.prototype);

使用這樣一個(gè)方法去拿到Person.prototype對(duì)象作為原型的值,這樣Student.prototype原型就會(huì)有Person.prototype的值了。

如果去掉Object.create()的話。人有一些方法,但是學(xué)生也有自己的一些方法,Student.prototype = Person.prototype;Person.prototype;賦值給Student.prototype的時(shí)候,當(dāng)我想增加學(xué)生自己的方法時(shí),比如說(shuō)

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};

這樣的話由于他們指向的是同一個(gè)對(duì)象,給Student.prototype增加對(duì)象的時(shí)候同時(shí)也給Person.prototype;增加了同樣的屬性,這不是我們想要的。

所以說(shuō)通過(guò)Student.prototype = Object.create(Person.prototype);創(chuàng)建了一個(gè)空的對(duì)象,而這個(gè)空對(duì)象的原型指向了Person.prototype

這樣的話我們既可以在訪問Student.prototype的時(shí)候,可以向上查找Person.prototype同時(shí)可以在不影響Person.prototype的前提下創(chuàng)建一些自己的Student.prototype上的方法。

Student.prototype.constructor = Student;

每一個(gè)prototype屬性對(duì)象都會(huì)有一個(gè)constructor屬性,他的值是指向函數(shù)本身,實(shí)際上這里面沒有太大的用處,因?yàn)槲覀兛梢匀我獾娜バ薷模菫榱吮WC一致性,我們把這個(gè)改成Student.prototype.constructor = Student;

面向?qū)ο罄訙y(cè)試

function Person(name, age) {
    this.name = name;
    this.age = age;
};

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.legs_num = 2;
Person.prototype.arms_num = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
};

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;


Student.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new,and form" + this.className + ".");
};

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};


var t = new Student("黃繼鵬", 23, "class2");
var poi=new Person("李漢",22);
console.log(poi);
console.log(t);
Paste_Image.png

再談原型鏈

再談原型鏈

function Person(name, age) {
    this.name = name;
    this.age = age;
};

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.legs_num = 2;
Person.prototype.arms_num = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
};

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;


Student.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new,and form" + this.className + ".");
};

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};

console.log(Student.prototype);

var peng = new Student("黃繼鵬", 23, "class2");
peng.hi();
console.log(peng.legs_num);
peng.walk();
peng.learn('math')
dfg.png

這個(gè)圖里面說(shuō)明了上面代碼例子的示意圖

通過(guò)var peng = new Student("黃繼鵬", 23, "class2");來(lái)創(chuàng)建了一個(gè)實(shí)例peng

peng的實(shí)例他的原型我們用__proto__表示,就會(huì)指向構(gòu)造器Student.prototype的屬性。

Student.prototype上面有hilearn方法,Student.prototype是通過(guò)Student.prototype = Object.create(Person.prototype);構(gòu)造的,所以說(shuō)Student.prototype是一個(gè)對(duì)象,并且的原型指向Person.prototype

Person.prototype。也給她設(shè)置了很多屬性,hi...等。

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.hi其實(shí)是內(nèi)置的普通對(duì)象,內(nèi)置對(duì)象他本身也會(huì)有他的原型,他的原型就是Object.prototype

也就是因?yàn)檫@樣所以說(shuō)隨便一個(gè)對(duì)象才會(huì)有hasOwnPropertyvalueOftoString等一些公共的函數(shù),這些函數(shù)都是從Object.prototype而來(lái)的。

當(dāng)我們?nèi)フ{(diào)用

peng.hi();方法的時(shí)候,首先看這個(gè)對(duì)象上本身有沒有hi方法,在本身沒有所以會(huì)像上查找,差遭到peng原型也就是Student.prototype有這樣一個(gè)函數(shù)方法,所以最終調(diào)用的是Student.prototype上面的hi方法。

如果Student.prototype不去寫hi方法的時(shí)候peng.hi();會(huì)去調(diào)用Person.prototype.hi這樣一個(gè)方法,

當(dāng)我們調(diào)用peng.walk();的時(shí)候,先找peng上發(fā)現(xiàn)沒有,然后Student.prototype上面,也沒有,Person.prototypewalk所以最終調(diào)用結(jié)果是Person.prototype上面的walk方法。

那么我想去調(diào)用peng.toString的時(shí)候也是一層一層向上查找。找到Object.prototype那么最后到null也就是最根源沒有了。

關(guān)于一切的一般對(duì)象都會(huì)指向Object.prototype做一個(gè)實(shí)際的實(shí)驗(yàn)

var obj={x:1,y:2}

比如用obj等于一個(gè)花括號(hào)空的字面量,給他屬性。

那么我們知道obj就是一個(gè)普通的對(duì)象,obj.x就為1

可以通過(guò)obj.__proto__這樣的機(jī)制可以讓你去訪問對(duì)象的原型

Paste_Image.png

除了obj.__proto__以外,在es5里面提供了一個(gè)方法能夠返回一個(gè)對(duì)象的原型,就是Object.getPrototypeOf(obj)這樣一個(gè)方法,可以返回對(duì)象原型,

Paste_Image.png

通過(guò)三個(gè)等號(hào)來(lái)判斷Object.getPrototypeOf(obj)是不是等于Object.prototype

Paste_Image.png

返回true

也就是說(shuō)我們隨便一個(gè)對(duì)象仔面了也好或者是函數(shù)函數(shù)內(nèi)置的prototype屬性然后去判斷 他的原型可以看到也是Object.prototype

Paste_Image.png

也正因?yàn)槿绱怂哉f(shuō)我們才可以調(diào)用obj.toString()obj.valueOf()
實(shí)際上這些方法都是取自Object.prototype上的,

Paste_Image.png

并不是所有對(duì)象最終原型鏈上最終都有Object.prototype

比如說(shuō)我們創(chuàng)建obj2對(duì)象,然后用var obj2=Object.create(null)obj2.create(null)的作用是創(chuàng)建空對(duì)象,并且這個(gè)對(duì)象的原型指向這樣一個(gè)參數(shù),但是這里參數(shù)是null,obj2這個(gè)時(shí)候他的原型就是undefinedobj2.toString就是undefined那么通過(guò)Object.create(null)創(chuàng)建出來(lái)的對(duì)象,就沒有Object.prototype的一些方法。所以說(shuō)并不是所有的對(duì)象都繼承Object.prototype

只是一般我們對(duì)象字面量或者是函數(shù)的prototype預(yù)制的一般的對(duì)象上都有Object.prototype

Paste_Image.png

并不是所有的函數(shù)對(duì)象都有prototype這樣一個(gè)預(yù)制屬性的

function abc() {};
console.log(abc.prototype);
var hh = abc.bind(null);
console.log(hh.prototype);
Paste_Image.png

使用es5友誼和bind函數(shù),bind函數(shù)是用來(lái)修改函數(shù)在運(yùn)行時(shí)的this的,bind函數(shù)返回的也是一個(gè)函數(shù),但是bind函數(shù)就沒有prototype預(yù)設(shè)屬性。

prototype屬性

javascript中的prototype原型,不像java的class,是一旦寫好了以后不太容易去動(dòng)態(tài)改變的,但是javascript中原型實(shí)際上也是普通的對(duì)象,那么意味著在程序運(yùn)行的階段我們也可以動(dòng)態(tài)的給prototype添加或者刪除一些屬性,

function Person(name, age) {
    this.name = name;
    this.age = age;
};

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.legs_num = 2;
Person.prototype.arms_num = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
};

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;


Student.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new,and form" + this.className + ".");
};

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};

console.log(Student.prototype);

var peng = new Student("黃繼鵬", 23, "class2");
peng.hi();
console.log(peng.legs_num);
peng.walk();
peng.learn('math')

Student.prototype.x=101;
console.log(peng.x);//101

Student.prototype={y:2};
console.log(peng.y);//undefined
console.log(peng.x);//101

var nunnly=new Student("nunnly", 23, "class3");

console.log(nunnly.y);//2
console.log(nunnly.x);//undefined
Paste_Image.png
Student.prototype.x=101;
console.log(peng.x);//101

Student.prototype={y:2};
console.log(peng.y);//undefined
console.log(peng.x);//101

var nunnly=new Student("nunnly", 23, "class3");

console.log(nunnly.y);//2
console.log(nunnly.x);//undefined

比如說(shuō)這里的Student.prototype同過(guò)Student.prototype.x=101;huang的原型動(dòng)態(tài)的添加一個(gè)屬性x那么我們發(fā)現(xiàn)所有的實(shí)例都會(huì)受到影響,現(xiàn)在去調(diào)用console.log(peng.x);發(fā)現(xiàn)他賦值為101了,

直接修改Student.prototype={y:2};構(gòu)造器的屬性,把他賦值為一個(gè)新的對(duì)象,y:2

有趣的現(xiàn)象

console.log(peng.y);//undefined
console.log(peng.x);//101

當(dāng)我們?nèi)バ薷?code>Student.prototype的時(shí)候并不能修改已經(jīng)實(shí)例化的對(duì)象,也就是說(shuō)已經(jīng)實(shí)例化的peng他的原型已經(jīng)指向當(dāng)時(shí)的Student.prototype如果你修改了Student.prototype的話,并不會(huì)影響已經(jīng)創(chuàng)建的實(shí)例,之所以修改的x沒有問題,是因?yàn)槲覀冃薷牡氖?code>peng原型的那個(gè)對(duì)象,

但是再去用new重新實(shí)例化對(duì)象,那么會(huì)發(fā)現(xiàn)x不見了,并且y是新的y值。

內(nèi)置構(gòu)造器的prototype

Object.prototype.x = 1;
var obj = {
    y: 3
};
console.log(obj.x); //1
for (var key in obj) {
    console.log(key + "=" + obj[key]); //y=3 x=1
}

比如說(shuō)我們想讓所有的對(duì)象他的原型鏈上都會(huì)有x屬性會(huì)發(fā)現(xiàn)所有對(duì)象都會(huì)有x屬性,這樣的設(shè)置會(huì)在for...in的時(shí)候會(huì)被枚舉出來(lái),那么怎么解決這個(gè)問題呢

Object.defineProperty(Object.prototype, 'x', {writable: true,value: 1});
var obj = {
    y: 3
};
console.log(obj.x); //1
for (var key in obj) {
    console.log(key + "=" + obj[key]); //y=3
}
  • value:屬性的值給屬性賦值
  • writable:如果為false,屬性的值就不能被重寫。
  • get: 一旦目標(biāo)屬性被訪問就會(huì)調(diào)回此方法,并將此方法的運(yùn)算結(jié)果返回用戶。
  • set:一旦目標(biāo)屬性被賦值,就會(huì)調(diào)回此方法。
  • configurable:如果為false,則任何嘗試刪除目標(biāo)屬性或修改屬性以下特性(writable, configurable, enumerable)的行為將被無(wú)效化。
  • enumerable:是否能在for...in循環(huán)中遍歷出來(lái)或在Object.keys中列舉出來(lái)。

創(chuàng)建對(duì)象-new/原型鏈

function foo(){}    //定義函數(shù)對(duì)象 foo
foo.prototype.z = 3;      //函數(shù)對(duì)象默認(rèn)帶foo.prototype對(duì)象屬性  這個(gè)對(duì)象會(huì)作為new實(shí)例的對(duì)象原型  對(duì)象添加z屬性=3

var obj =new foo();    //用構(gòu)造器方式構(gòu)造新的對(duì)象
obj.y = 2;    //通過(guò)賦值添加2個(gè)屬性給obj
obj.x = 1;   //通過(guò)new去構(gòu)造這樣一個(gè)對(duì)象他的主要特點(diǎn)是,他的原型會(huì)指向構(gòu)造器的foo.prototype屬性

//一般foo.prototype對(duì)象他的原型又會(huì)指向Object.prototype
//Object.prototype他也會(huì)有他的原型最后指向null整個(gè)原型鏈的末端

obj.x; // 1  //訪問obj.x發(fā)現(xiàn)對(duì)象上有x返回1
obj.y; // 2  //訪問obj.y發(fā)現(xiàn)對(duì)象上有x返回2
obj.z; // 3  //obj上沒有z并不會(huì)停止查找,會(huì)去查找他的原型foo.prototype.z返回3
typeof obj.toString; // ‘function'  這是一個(gè)函數(shù),toString是Object.prototype上面的每個(gè)對(duì)象都有
'z' in obj; // true     obj.z是從foo.prototype繼承而來(lái)的,所以說(shuō)obj里面有z
obj.hasOwnProperty('z'); // false   表示z并不是obj直接對(duì)象上的,而是對(duì)象原型鏈上的。
Paste_Image.png

instanceof

instanceof

instanceof數(shù)據(jù)類型判斷方法

console.log([1, 2] instanceof Array); //true
console.log(new Object() instanceof Array); //false

左邊要求是一個(gè)對(duì)象instanceof右邊要求是一個(gè)函數(shù)或者說(shuō)構(gòu)造器
他會(huì)判斷右邊的構(gòu)造器的 prototype的屬性是否出現(xiàn)在左邊這個(gè)對(duì)象的原型鏈上。

console.log([1, 2] instanceof Array); //true

[1,2]這里是數(shù)組字面量,數(shù)組的字面量他也有他的原型,他的原型就是Array.prototype所以返回true

console.log(new Object() instanceof Array); //false

new Object()new一個(gè)空對(duì)象空對(duì)象的原型會(huì)指向Object.prototypenew Object()的原型鏈不是Array.prototype所以返回false

需要注意的是

console.log([1, 2] instanceof Object); //true

因?yàn)閿?shù)組他的原型是Array.prototype,而Array.prototype的原型就是Object.prototype,所以返回true

所以說(shuō)instanceof我們可以判斷某一個(gè)對(duì)象他的原型鏈上是否有右邊這個(gè)函數(shù)構(gòu)造器的prototype對(duì)象屬性。

function per() {};

function sor() {};
sor.prototype = new per();
sor.prototype.constructor = sor;

var peng = new sor();
var han = new per();
console.log(peng instanceof sor); //true
console.log(peng instanceof per); //true
console.log(han instanceof sor); //false
console.log(han instanceof per); //true

實(shí)現(xiàn)繼承的方式

實(shí)現(xiàn)繼承的方式

if (!Object.create) {
    Object.create = function(proto) {
        function F() {};
        F.prototype = proto;
        return new F();
    };
}


function Person(name, age) {
    this.name = name;
    this.age = age;
};

Person.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new");
};

Person.prototype.legs_num = 2;
Person.prototype.arms_num = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
};

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;


Student.prototype.hi = function() {
    console.log('Hi my name is' + this.name + ",I'm" + this.age + "years old new,and form" + this.className + ".");
};

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
};

console.log(Student.prototype);

var t = new Student("黃繼鵬", 23, "class2");
t.hi();
console.log(t.legs_num);
t.walk();
t.learn('math');

Object.create()也有他的問題,他是es5之后才支持的,但是沒有關(guān)系在es5之前我們可以寫一個(gè)模擬的方法。

if (!Object.create) {
    Object.create = function(proto) {
        function F() {};
        F.prototype = proto;
        return new F();
    };
}

這里面我們可以判斷下有沒有Object.create如果沒有的話,我們可以把他賦值為一個(gè)函數(shù),這里會(huì)傳進(jìn)來(lái)一個(gè)參數(shù),寫一個(gè)臨時(shí)的空函數(shù),把空函數(shù)的prototype屬性賦值給想要作為原型的對(duì)象,然后返回new F(),會(huì)創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象的原型指向構(gòu)造器的prototype,利用這樣的規(guī)則返回空對(duì)象,并且對(duì)象原型指向參數(shù)也就是要繼承的原型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評(píng)論 3 421
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,935評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,325評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,534評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,892評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,322評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,800評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,084評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容