js高级第三天(原型链及继承)
生活随笔
收集整理的這篇文章主要介紹了
js高级第三天(原型链及继承)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原型及原型鏈
原型鏈:是一種關系,實例對象和原型對象之間的關系,關系是通過原型(proto)來聯系的
//使用對象---->使用對象中的屬性和對象中的方法,使用對象就要先有構造函數//構造函數function Person(name,age) {//屬性this.name=name;this.age=age;//在構造函數中的方法this.eat=function () {console.log("吃好吃的");};}//添加共享的屬性Person.prototype.sex="男";//添加共享的方法Person.prototype.sayHi=function () {console.log("您好啊,怎么這么帥,就是這么帥");};//實例化對象,并初始化var per=new Person("小明",20);per.sayHi();//如果想要使用一些屬性和方法,并且屬性的值在每個對象中都是一樣的,方法在每個對象中的操作也都是一樣,那么,為了共享數據,節省內存空間,是可以把屬性和方法通過原型的方式進行賦值console.dir(per);//實例對象的結構console.dir(Person);//構造函數的結構//實例對象的原型__proto__和構造函數的原型prototype指向是相同的//實例對象中的__proto__原型指向的是構造函數中的原型prototypeconsole.log(per.__proto__==Person.prototype);//實例對象中__proto__是原型,瀏覽器使用的//構造函數中的prototype是原型,程序員使用的//原型鏈:是一種關系,實例對象和原型對象之間的關系,關系是通過原型(__proto__)來聯系的1.原型指向是可以改變的
//人的構造函數function Person(age) {this.age=10;}//人的原型對象方法Person.prototype.eat=function () {console.log("人的吃");};//學生的構造函數function Student() {}Student.prototype.sayHi=function () {console.log("嗨,小蘇你好帥哦");};//學生的原型,指向了一個人的實例對象Student.prototype=new Person(10);var stu=new Student();stu.eat();stu.sayHi();//原型指向可以改變//實例對象的原型__proto__指向的是該對象所在的構造函數的原型對象//構造函數的原型對象(prototype)指向如果改變了,實例對象的原型(__proto__)指向也會發生改變2.原型最終指向哪里
function Person() {}Person.prototype.eat=function () {console.log("吃東西");};var per=new Person();console.dir(per);console.dir(Person);//實例對象中有__proto__原型//構造函數中有prototype原型//prototype是對象//所以,prototype這個對象中也有__proto__,那么指向了哪里//實例對象中的__proto__指向的是構造函數的prototype//所以,prototype這個對象中__proto__指向的應該是某個構造函數的原型prototype//Person的prototype中的__proto__的指向//console.log(Person.prototype.__proto__);//per實例對象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是nullconsole.log(per.__proto__==Person.prototype);console.log(per.__proto__.__proto__==Person.prototype.__proto__);console.log(Person.prototype.__proto__==Object.prototype);console.log(Object.prototype.__proto__);3.如果原型指向改變了,那么就應該在原型改變指向之后添加原型方法
function Person(age) {this.age = age;}//指向改變了Person.prototype = {eat: function () {console.log("吃");}};//先添加原型方法Person.prototype.sayHi = function () {console.log("您好");};var per = new Person(10);per.sayHi();4.實例對象的屬性和原型對象中的屬性重名問題
function Person(age,sex) {this.age=age;this.sex=sex;}Person.prototype.sex="女";var per=new Person(10,"男");console.log(per.sex);//因為JS是一門動態類型的語言,對象沒有什么,只要點了,那么這個對象就有了這個東西,沒有這個屬性,只要對象.屬性名字,對象就有這個屬性了,但是,該屬性沒有賦值,所以,結果是:undefinedconsole.log(per.fdsfdsfsdfds);console.log(fsdfdsfds);//實例對象訪問這個屬性,應該先從實例對象中找,找到了就直接用,找不到就去指向的原型對象中找,找到了就使用,找不到呢?=====//通過實例對象能否改變原型對象中的屬性值?不能//就想改變原型對象中屬性的值,怎么辦?直接通過原型對象.屬性=值;可以改變 // Person.prototype.sex="哦嘜嘎的"; // per.sex="人"; // console.log(per.sex); // // console.dir(per);5.一個神奇的原型鏈
<div id="dv"></div> <script>var divObj=document.getElementById("dv");console.dir(divObj);//divObj.__proto__---->HTMLDivElement.prototype的__proto__--->HTMLElement.prototype的__proto__---->Element.prototype的__proto__---->Node.prototype的__proto__---->EventTarget.prototype的__proto__---->Object.prototype沒有__proto__,所以,Object.prototype中的__proto__是null</script>繼承
/*** 面向對象編程思想:根據需求,分析對象,找到對象有什么特征和行為,通過代碼的方式來實現需求,要想實現這個需求,就要創建對象,要想創建對象,就應該顯示有構造函數,然后通過構造函數來創建對象.,通過對象調用屬性和方法來實現相應的功能及需求,即可* 首先JS不是一門面向對象的語言,JS是一門基于對象的語言,那么為什么學習js還要學習面向對象,因為面向對象的思想適合于人的想法,編程起來會更加的方便,及后期的維護....* 面向對象的編程語言中有類(class)的概念(也是一種特殊的數據類型),但是JS不是面向對象的語言,所以,JS中沒有類(class),但是JS可以模擬面向對象的思想編程,JS中會通過構造函數來模擬類的概念(class)***** 小明,小紅,小麗,小白,小花 都是人* 共同的特征和行為* 特征--->屬性* 行為---方法** 面向對象的特性:封裝,繼承,多態** 封裝:就是包裝* 一個值存儲在一個變量中--封裝* 一坨重復代碼放在一個函數中--封裝* 一系列的屬性放在一個對象中--封裝* 一些功能類似的函數(方法)放在一個對象中--封裝* 好多相類似的對象放在一個js文件中---封裝** 繼承: 首先繼承是一種關系,類(class)與類之間的關系,JS中沒有類,但是可以通過構造函數模擬類,然后通過原型來實現繼承* 繼承也是為了數據共享,js中的繼承也是為了實現數據共享** 原型作用之一:數據共享,節省內存空間* 原型作用之二:為了實現繼承** 繼承是一種關系:** 父類級別與類級別的關系** 例子:** 小楊--->人, 姓名, 有錢, 帥, 有功夫--降龍十八掌* 小楊子-->人,* 繼承:* 姓氏----繼承* 外表----繼承* 財產----繼承* 功夫---繼承*** 人: 姓名, 性別, 年齡 ,吃飯, 睡覺** 學生類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 學習行為* 老師類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資,教學行為* 程序員: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資, 敲代碼* 司機類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資 開車*** 動物類別: 體重, 顏色, 吃* 狗類別: 體重,顏色, 吃, 咬人* 二哈類別: 體重,顏色, 吃, 咬人 逗主人開心,汪汪,你好帥** 多態:一個對象有不同的行為,或者是同一個行為針對不同的對象,產生不同的結果,要想有多態,就要先有繼承,js中可以模擬多態,但是不會去使用,也不會模擬,*** */ //例子://人,都有姓名,性別,年齡, 吃飯, 睡覺, 玩//學生,都有姓名,性別,年齡, 成績, 吃飯, 睡覺, 玩 ,學習的行為//js中通過原型來實現繼承function Person(name,age,sex) {this.name=name;this.sex=sex;this.age=age;}Person.prototype.eat=function () {console.log("人可以吃東西");};Person.prototype.sleep=function () {console.log("人在睡覺");};Person.prototype.play=function () {console.log("生活就是不一樣的玩法而已");};function Student(score) {this.score=score;}//改變學生的原型的指向即可==========>學生和人已經發生關系Student.prototype=new Person("小明",10,"男");Student.prototype.study=function () {console.log("學習很累很累的哦.");};//相同的代碼太多,造成了代碼的冗余(重復的代碼)var stu=new Student(100);console.log(stu.name);console.log(stu.age);console.log(stu.sex);stu.eat();stu.play();stu.sleep();console.log("下面的是學生對象中自己有的");console.log(stu.score);stu.study();1.繼承小案例
//動物有名字,有體重,有吃東西的行為//小狗有名字,有體重,有毛色, 有吃東西的行為,還有咬人的行為//哈士奇名字,有體重,有毛色,性別, 有吃東西的行為,還有咬人的行為,逗主人開心的行為//動物的構造韓素function Animal(name,weight) {this.name=name;this.weight=weight;}//動物的原型的方法Animal.prototype.eat=function () {console.log("天天吃東西,就是吃");};//狗的構造函數function Dog(color) {this.color=color;}Dog.prototype=new Animal("哮天犬","50kg");Dog.prototype.bitePerson=function () {console.log("哼~汪汪~咬死你");};//哈士奇function ErHa(sex) {this.sex=sex;}ErHa.prototype=new Dog("黑白色");ErHa.prototype.playHost=function () {console.log("哈哈~要壞衣服,要壞桌子,拆家..嘎嘎...好玩,開心不,驚喜不,意外不");};var erHa=new ErHa("雄性");console.log(erHa.name,erHa.weight,erHa.color);erHa.eat();erHa.bitePerson();erHa.playHost();2.借用構造函數實現繼承
為了數據共享,改變原型指向,做到了繼承—通過改變原型指向實現的繼承
缺陷:因為改變原型指向的同時實現繼承,直接初始化了屬性,繼承過來的屬性的值都是一樣的了,所以,這就是問題
只能重新調用對象的屬性進行重新賦值,
解決方案:繼承的時候,不用改變原型的指向,直接調用父級的構造函數的方式來為屬性賦值就可以了------借用構造函數:把要繼承的父級的構造函數拿過來,使用一下就可以了
借用構造函數:構造函數名字.call(當前對象,屬性,屬性,屬性…);
解決了屬性繼承,并且值不重復的問題
缺陷:父級類別中的方法不能繼承
3.組合繼承
組合繼承:原型繼承+借用構造函數繼承
function Person(name,age,sex) {this.name=name;this.age=age;this.sex=sex;}Person.prototype.sayHi=function () {console.log("阿涅哈斯誒呦");};function Student(name,age,sex,score) {//借用構造函數:屬性值重復的問題Person.call(this,name,age,sex);this.score=score;}//改變原型指向----繼承Student.prototype=new Person();//不傳值Student.prototype.eat=function () {console.log("吃東西");};var stu=new Student("小黑",20,"男","100分");console.log(stu.name,stu.age,stu.sex,stu.score);stu.sayHi();stu.eat();var stu2=new Student("小黑黑",200,"男人","1010分");console.log(stu2.name,stu2.age,stu2.sex,stu2.score);stu2.sayHi();stu2.eat();//屬性和方法都被繼承了4.拷貝繼承
把一個對象中的屬性或者方法直接復制到另一個對象中
直接遍歷的方式復制到另一個對象中
函數
//函數的聲明function f1() {console.log("我是函數");}f1();//函數表達式var ff=function () {console.log("我也是一個函數");};ff();1.函數聲明和函數表達式的區別
函數聲明如果放在if-else的語句中,在IE8的瀏覽器中會出現問題
以后寧愿用函數表達式,都不用函數聲明
2.函數中this指向的問題
/*** 函數中的this的指向*** 普通函數中的this是誰?-----window* 對象.方法中的this是誰?----當前的實例對象* 定時器方法中的this是誰?----window* 構造函數中的this是誰?-----實例對象* 原型對象方法中的this是誰?---實例對象*** *///嚴格模式: // "use strict";//嚴格模式 // function f1() { // console.log(this);//window // } // f1();//普通函數// function f1() {// console.log(this);// }// f1();//定時器中的this// setInterval(function () {// console.log(this);// },1000);//構造函數// function Person() {// console.log(this);//對象的方法// this.sayHi=function () {// console.log(this);// };// }//原型中的方法// Person.prototype.eat=function () {// console.log(this);// };// var per=new Person();// console.log(per);// per.sayHi();// per.eat();//BOM:中頂級對象是window,瀏覽器中所有的東西都是window的3.函數的不同調用方式
//普通函數function f1() {console.log("文能提筆控蘿莉");}f1();//構造函數---通過new 來調用,創建對象function F1() {console.log("我是構造函數,我驕傲");}var f=new F1();//對象的方法function Person() {this.play=function () {console.log("玩代碼");};}var per=new Person();per.play();4.函數是對象,對象不一定是函數
//對象中有__proto__原型,是對象//函數中有prototype原型,是對象// function F1() { // } // // console.dir(F1);//有prototype,又有__proto__ // // console.dir(Math);//中有__proto__,但是沒有prorotype // // //對象中有__proto__,函數中應該有prototype // // 如果一個東西里面有prototype,又有__proto__,說明是函數,也是對象// // function F1(name) { // this.name=name; // } // // console.dir(F1);//所有的函數實際上都是Function的構造函數創建出來的實例對象 // var f1=new Function("num1","num2","return num1+num2"); // console.log(f1(10,20)); // console.log(f1.__proto__==Function.prototype);//所以,函數實際上也是對象// console.dir(f1);console.dir(Function);5.數組的函數調用
//數組可以存儲任何類型的數據var arr=[function () {console.log("十一假期快樂");},function () {console.log("十一假期開心");},function () {console.log("十一假期健康");},function () {console.log("十一假期安全");},function () {console.log("十一假期如意");}];//回調函數:函數作為參數使用arr.forEach(function (ele) {ele();});總結
以上是生活随笔為你收集整理的js高级第三天(原型链及继承)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超经典的广告语
- 下一篇: Windows 下安装sql serve