一、對象
- 對象(object)是某一個類(class)的實例(instance)
- 類可以理解成模具
- 對象可以理解成模具開發(fā)的產(chǎn)品
- 對象的另一個特性就是封裝:把細節(jié)隱藏掉,想要修改對象的屬性需要通過它提供的方法去訪問
//用一個構造函數(shù)Fn生成了一個對象p; 對象p繼承自構造函數(shù)Fn()
function Fn(){
console.log('name:Ceaser');
}
//通過類Fn(),生成屬于這個類型的對象p
//一個函數(shù)通過new操作符,可以讓一個函數(shù)作為構造函數(shù)生成一個對象
var p = new Fn();
typeof p; //object
//所以這個對象p就是這個類的實例
p instanceof Fn; //true p是Fn的實例
//p1和p2作為兩個不同的新實例(創(chuàng)建了不同的副本),對類(屬性的值)做修改互不影響
function Fn(){
this.name = 'hunger';
this.age = 18;
}
var p1 = new Fn();
var p2 = new Fn();
p1.name = 'velley';
console.log(p2); //hunger
//根據(jù)參數(shù)需要把參數(shù)設置為變量
function Fn(name, age){
this.name = name;
this.age = age;
}
var p1 = new Fn('hunger', 21);
var p2 = new Fn('velley', 14);
//調(diào)用對象的方法
function Fn(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '說: 我' + this.age + '歲了。');
}
}
var p1 = new Fn('hunger', 21);
var p2 = new Fn('velley', 14);
p1.say(); //hunger說: 我21歲了。
p2.say(); //velley說: 我14歲了。
//注意:不使用new,p1為undefined 28.24-31.05
function Fn(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '說: 我' + this.age + '歲了。');
}
}
var p1 = Fn('hunger', 21);
var p2 = new Fn('velley', 14);
console.log(p1); //undefined
二、原型
- 構造函數(shù)Person中存在屬性prototype,屬性prototype指向原型對象Prototype
原型對象Propotype包括:構造器constructor(指向構造函數(shù)Person) 和 原型屬性_ proto_ 以及 自己定義的方法或?qū)傩裕?br> 當通過new方法創(chuàng)建構造函數(shù)Person的實例后得到對象p1,實例的_ proto_指向它的創(chuàng)造者Person的整個原型Propotype
此時對象p1包括:name:hunger、age:21、以及繼承自p1的原型屬性_ proto_
function Person(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '說: 我' + this.age + '歲了。');
}
}
var p1 = new Person('hunger', 21);
- 原型對象是對象實例的公共空間。
可以通過對象實例訪問保存再原型對象中的值,但不能通過對象實例重寫原型中的值
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this.name + '說: 我' + this.age + '歲了。');
}
}
Person.prototype = {
friend: 'Cherry'
}
var p1 = new Person('hunger', 21);
p1.friend = 'Neco';
console.log(p1.friend); //Neco
var p2 = new Person('Danee', 22);
console.log(p2.friend); //Cherry

Person對象的_proto_ 與 Prototype原型對象的_proto_ 指向Object對象

原型
三、原型鏈
-
對象實例p1訪問屬性時先從繼承來的在構造函數(shù)Person的屬性中查找,查找不到時再從構造函數(shù)Person的原型對象Prototype中查找
原型鏈 - 調(diào)用
p2.name,對象實例p2沒有name屬性,此時要從原型上查找。得到hello
原型鏈 - 深入:
_ proto_指向構造它的函數(shù)的原型對象,prototype指向它自身的函數(shù)的原型對象
任何對象都是被創(chuàng)建出來的,對象內(nèi)部都存在原型屬性_proto_,_proto_保存著構造它的原型對象
對象Person里面有屬性prototype,證明Person本身是一個對象(函數(shù)也是一種對象),所以對象Person內(nèi)部也存在原型屬性_proto_
原型對象Prototype也存在屬性_proto_
Object在JS中本身是一個函數(shù)function(){ [native code] },new Object才是創(chuàng)建一個對象Object{}
任何對象都是由Object函數(shù)創(chuàng)建的(即new Object方式)
Object.prototype === Person.prototype._proto_返回true證明原型對象Prototype的創(chuàng)建者是Object。因為原型對象Prototype的原型屬性_ proto_指向Object的原型對象Prototype
由此證明:原型對象Prototype的創(chuàng)建者是構造函數(shù)Object
function Person(name) {
this.name = name;
}
Person.prototype = {
sayName: function(){
console.log('My name is: ' + this.name);
}
}
var p1 = new Person('hunger');
var p2 = new Person('danee');
p1.sayName();

image.png
原型對象只有一個 [[prototype]] 正常的是隱藏的 訪問不到,瀏覽器為了讓你訪問到,弄了個__proto__屬性任何一個函數(shù)都擁有prototype,任何一個對象都擁有_ proto_
函數(shù)中的prototype是創(chuàng)建時就有的
對象中的_ proto_是對象的創(chuàng)造者(即構造函數(shù)中的prototype)
因為對象都是由Object函數(shù)創(chuàng)建的,所以對象的屬性_ proto_指向函數(shù)的prototype
上例:
Person.prototype.__proto__ === Object.prototypep1.__proto__ === Person.prototype
image.png

image.png

原型鏈
四、基本包裝類型
var str = 'hellow';
等同于
var str = new String('hellow');

基本包裝類型

image.png
四、繼承
function Cake(name, size){
console.log(this);
this.name = name;
this.size = size;
}
Cake.prototype.sayName = function(){
console.log('I am :' + this.name);
}
Cake.prototype.saySize = function(){
console.log('My size is' + this.size);
}
//在函數(shù)MilkCake的作用域里執(zhí)行Cake函數(shù)(此時MilkCake取得了Cake的屬性)
function MilkCake(name, size, taste){
console.log(this);
Cake.apply(this, [name, size]);
this.taste = taste;
}
//創(chuàng)建一個Cake的對象實例指向 MilkCake的原型對象(此時MilkCake繼承了Cake的屬性及原型對象)
MilkCake.prototype = new Cake();
//將MilkCake原型對象的構造器指向MilkCake函數(shù)
MilkCake.prototype.constructor = MilkCake;
var Cake1 = new MilkCake('牛奶蛋糕', 16, '甜');
console.log(Cake1);
constructor返回創(chuàng)建實例對象的構造函數(shù)的引用,所有對象都會從它的原型對象上繼承一個constructor屬性

image.png

image.png
- 繼承原型函數(shù)方法(Es5簡便方法)
function inherit(superType, subType){
//拷貝一份父函數(shù)的原型對象
var _prototype = Object.create(superType.prototype);
//將拷貝原型對象的構造器指向子函數(shù)
_prototype.constructor = subType;
//將拷貝的原型對象指向子函數(shù)的prototype屬性
subType.prototype = _prototype;
}
inherit(superType, subType);

image.png

