構造函數的形式
1,使用new關鍵字創建對象
2,使用構造函數,把新創建出來的對象,賦值給構造函數內的this
構造函數有哪些,3,在構造函數內使用this為新創建出來的對象新增成員
4,默認返回新創建的這個對象
function Animal(name,type,){this.name =name;this.type =type;this.barkWay = function(){console.log('汪汪汪')}}var dog =new Animal('大黃','dog');dog.barkWay();//汪汪汪
注意:如果想使用正常的函數一樣使用構造函數
1,構造函數中的this將不再指向新創建出來的對象
構造函數原型原型鏈關系,2,構造函數中的this這個時候多指向window對象,當使用this給對象添加成員的時候,全部添加到window上
構造函數存在的問題
構造函數中的方法,每新創建一個對象的時候,該對象都會重新創建方法,每個對象獨占一個方法,但是該方法內容完全相同,所以造成資源浪費
function Animal(){this.name = '大黃';this.type ='dog';this.age =15;this.bark = function(){console.log('汪汪汪')} } var dog = new Animal(); var cat = new Animal();dog.bark();//汪汪汪cat.bark();//汪汪汪
解決方法1
es5構造函數、將構造函數內的房進行提取放到構造函數外面,在構造函數內部引用,那么創建出來的對象,都會指向構造函數外面的這個函數,達到共享的目的
function barkWay(){console.log(this.type +this.yell)}function Animal(name,type,yell){this.name = name;this.type = type;this.yell =yell;this.bark =barkWay;}var dog = new Animal('大黃','狗','汪汪汪');var cat = new Animal('小花','貓','喵喵喵');cat.bark();//貓喵喵喵dog.bark();//狗汪汪汪
問題:全局變量增多,造成全局變量污染,代碼結構混亂,不易維護
?
解決方法2
構造函數原型是什么、使用原型
function Animal(name,type,yell){this.name = name;this.type = type;this.yell =yell;}Animal.prototype.bark =function(){console.log(this.type + this.yell)};var dog = new Animal('大黃','狗','汪汪汪');var cat = new Animal('小花','貓','喵喵喵');cat.bark();//貓喵喵喵dog.bark();//狗汪汪汪
原型: 在構造函數創建出來的時候,系統會默認的創建并關聯一個對象,這個對象就是原型,原型對象默認是空對象
原型的作用:原型中的成員,可以被使用和它關聯的構造函數創建出來的所有對象共享
?
js構造函數和原型、當使用對象訪問屬性和方法的時候,會首先在對象內部進行查找,如果找到了,就直接使用,如果沒有找到,就去原型中查找,查找到之后使用,如果原型中沒有,如果是屬性就是undefined,如果是方法就是報錯
function Person(name,age,sing){this.name = name ;this.age =age;this.sing =sing;}Person.prototype.sayHello = function(){console.log("你好我是"+this.name); };Person.prototype.singName = function(){console.log(this.sing)};var p = new Person('張學友',18,'一千個傷心的理由');var p1 = new Person('劉德華',28,'忘情水');p.sayHello();//你好我是張學友p1.sayHello();//你好我是劉德華 p.singName();//一千個傷心的理由p1.singName();//忘情水
原型對象的使用
?1,使用對象的動態特性,為原型對象添加成員
?2, 直接替換原型對象
復制構造函數的原型??
?如果使用第二種方法使用原型,會出現如下問題
在替換原型之前創建的對象和在替換原型之后的創建的對象的原型,,不是同一個
function Person(name,age,sing){this.name = name ;this.age =age;this.sing =sing;}Person.prototype.sayHello = function(){console.log("你好我是"+this.name);//你好我是劉能 };var p = new Person('劉能',18,'male');p.sayHello();Person.prototype ={msg:'你猜我在不在'};var p1 =new Person('劉二狗',24,'male');console.log(p1.msg);//你猜我在不在p1.sayHello();//Uncaught TypeError: p1.sayHello is not a functionp.sayHello();//Uncaught TypeError: p.sayHello is not a function
使用原型的注意事項
原型繼承和構造函數繼承區別。1,使用對象訪問屬性的時候,如果在本身內找不到就 回去原型中查找,但是使用點語法進行屬性賦值的時候,并不會去原型中進行查找,使用點語法賦值的時候,
如果對象不存在該屬性,就會給該對象新增該屬性,而不會修改原型中的屬性
function Person(){}Person.prototype.name ="張三";Person.prototype.age =18;var p = new Person();console.log(p.name);//張三p.name ="李四";console.log(p.name);//李四var p1 =new Person();console.log(p1.name)//張三
2,如果在原型中的屬性是引用類型的屬性,那么所有對象共享該屬性,并且一個對象修改了該引用類型中的成員,其他都會受到影響
function Person(){}Person.prototype.name ="張三";Person.prototype.age =18;var x = {brand:'奧迪',type:'A7'};Person.prototype.car =x;var p = new Person();console.log(p.car.brand);//奧迪Person.prototype.car ={brand: 'BYD'};var p1 =new Person();console.log(p.car.brand);//BYDconsole.log(p1.car.brand);//BYD
3,一般情況下不會講屬性添加到原型中,只會將需要共享的方法,添加到原型對象中
構造函數原理,?