var Car = {
color: 'red',//車的顏色
wheel: 4,//車輪數量
}
var Car2 = {
color: 'blue',
wheel: 4,
}
alert(Car.color);//red
複製代碼
function createCar(color,wheel) {
return {
color:color,
wheel:wheel
}
}
//而後生成實例對象,就等因而在調用函數:
var cat1 = createCar("紅色","4");
var cat2 = createCar("藍色","4");
alert(cat1.color);//紅色
複製代碼
function createCar(color,wheel){//createCar工廠
var obj = new Object;//或obj = {} 原材料階段
obj.color = color;//加工
obj.wheel = wheel;//加工
return obj;//輸出產品
}
//實例化
var cat1 = createCar("紅色","4");
var cat2 = createCar("藍色","4");
alert(cat1.color);//紅色
複製代碼
new
執行的函數構造內部變化:自動生成一個對象,this指向這個新建立的對象,函數自動返回這個新建立的對象function CreateCar(color,wheel){//構造函數首字母大寫
//不須要本身建立對象了
this.color = color;//添加屬性,this指向構造函數的實例對象
this.wheel = wheel;//添加屬性
//不須要本身return了
}
//實例化
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");
alert(cat1.color);//紅色
複製代碼
new CreateCar( )
出來的對象。alert(cat1.constructor == CreateCar); //true
alert(cat2.constructor == CreateCar); //true
複製代碼
__proto__
指向被實例化的構造函數的prototype,prototype默認帶constructor屬性,constructor指向構造函數。object instanceof constructor
運算符,驗證構造函數與實例對象之間的關係。alert(cat1 instanceof CreateCar ); //true
alert(cat2 instanceof CreateCar ); //true
複製代碼
構造函數方法很好用,可是存在一個浪費內存的問題。若是如今爲其再添加一個方法showWheel
。那麼,CreateCar就變成了下面這樣,這樣作有一個很大的弊端,對於每個實例對象,showWheel
都是如出一轍的內容,每一次生成一個實例,都必須生成重複的內容,多佔用一些內存。這樣既不環保,也缺少效率。html
function CreateCar(color,wheel){
this.color = color;
this.wheel = wheel;
this.showWheel = function(){//添加一個新方法
alert(this.wheel);
}
}
//仍是採用一樣的方法,生成實例:
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");
alert(cat1.showWheel == cat2.showWheel); //false
複製代碼
Javascript規定,每個構造函數都有一個prototype
屬性,指向另外一個對象。這個對象的全部屬性和方法,都會被構造函數的實例繼承。 這意味着,咱們能夠把那些不變的屬性和方法,直接定義在prototype對象上。__proto__
是原型鏈,指向實例化的函數原型。es6
function CreateCar(color,wheel){
//屬性寫構造函數裏面
this.color = color;
this.wheel = wheel;
}
//方法寫原型裏面
CreateCar.prototype.showWheel = function(){
alert(this.wheel);
}
CreateCar.prototype.showName = function(){
alert('車');
}
//生成實例。
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");
cat1.showName();//'車'
//這時全部實例的showWheel屬性和showName方法,其實都是同一個內存地址,指向prototype對象,所以就提升了運行效率。
alert(cat1.showWheel == cat2.showWheel );//true
alert(cat1.showName == cat2.showName );//true
console.log(cat1.__proto__ === CreateCar.prototype); //true
複製代碼
對象是由函數構造出來的。編程
Object.constructor == Function //true
複製代碼
function fn(){}
fn.constructor == Function //true
fn.constructor == Object //false
複製代碼
var obj = {};
obj.constructor === Object //true
複製代碼
只屬於類而不屬於實例化對象函數
function foo(){
this.show = function(){
return this;
}
}
foo.test = 123; //靜態屬性
foo.say = function(){
return this;
}
foo.say();
var fn = new foo(); //實例化的新的對象,this指向這個新的對象,不能訪問類的靜態方法
fn.say(); //Noname1.html:45 Uncaught TypeError: fn.say is not a function
console.log(foo.say() == fn.say());
複製代碼
call()
及for in
繼承 。 給對象的constructor.prototype添加方法屬性,對象就會繼承,若是要實現一個對象繼承其餘對象,採用以下方法。//人類
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.run = function(){
console.log('跑路~')
};
Person.prototype.say = function(){
console.log('說話~')
};
console.log(Person.prototype);
//男人
function Man(){
this.sex = "男";
}
Man.prototype = Person.prototype;
Man.prototype.yyy = function(){
console.log('嚶嚶嚶');
}
//會發現Person的prototype也改變了,由於複雜對象的賦值操做是引用而不是賦值
console.log(Person.prototype);
複製代碼
//人類
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.run = function(){
console.log('跑路~')
};
Person.prototype.say = function(){
console.log('說話~')
};
console.log(Person.prototype);
//男人
function Man(){
this.sex = "男";
}
for(var key in Person.prototype){
Man.prototype[key] = Person.prototype[key];
console.log(key)
}
Man.prototype.yyy = function(){
console.log('嚶嚶嚶');
}
console.log(Person.prototype);
var xm = new Man();
xm.yyy();
複製代碼
function ClassA(name){
this.name = name;
}
ClassA.prototype.say = function(){
console.log(666);
}
//中繼來作準備工做
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用
//須要來繼承ClassA
function ClassB(){}
ClassB.prototype = new Ready();//new 返回了一個新對象 __proto__指向被實例化的構造函數的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);
複製代碼
call
改變this指向function ClassA(name){
this.name = name;
}
ClassA.prototype.showName = function(){
console.log(this.name);
}
//中繼來作準備工做
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用
//須要來繼承ClassA
function ClassB(name){
ClassA.call(this,name);
}
ClassB.prototype = new Ready();//new 返回了一個新對象 __proto__指向被實例化的構造函數的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);
var xiaoming = new ClassB('小明');
xiaoming.showName();
複製代碼
同一個方法,面對不一樣的對象有不一樣的表現形式就叫作多態。ui
var obj = {
eat : function(_type){
if(_type == '貓'){
console.log('貓糧')
}else if (_type == "狗") {
console.log('狗糧')
}else{
console.log("吃飯");
}
}
};
obj.eat("狗");
複製代碼
查看該屬性是否在這個對象自己上,只有在自身屬性上纔會返回真,在原型鏈上會返回假。this
function ClassA(){}
ClassA.prototype.test = function(){
console.log('test')
}
var a = new ClassA();
a.test();
console.log(a.hasOwnProperty('test')); //false
複製代碼
描述符是對一個屬性的特性的描述,defineProperty
設置描述符(修飾符),value
設置屬性值,configurable
是否容許修飾符被改變 默認爲false,enumerable
是否能夠被枚舉 默認爲false,writable
是否能夠被 = 等號改變 默認爲false。es5
var obj = {
a : 1
};
var c = 666;
Object.defineProperty(obj,'c',{
//value : 233,
//enumerable : false,
//writable : true,//他的值可否改變
//設置的時候調用
set : function(n){
//n 就是等號的右邊的值
c = c*n;
},
//獲取的時候調用
get : function(){
return c;
},
configurable : true,//是否能夠再次修改修飾符
});
複製代碼