日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JavaScript高级学习(三)

發(fā)布時(shí)間:2023/12/18 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript高级学习(三) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一. 原型和原型鏈

實(shí)例對(duì)象中的__proto__原型指向的是構(gòu)造函數(shù)中的原型prototype

consolg.log(per.__proto__==Person.prptptype);//true


實(shí)例對(duì)象可以直接訪問(wèn)原型對(duì)象中的屬性或者方法。

原型鏈:實(shí)例對(duì)象和原型對(duì)象之間的關(guān)系,是通過(guò)原型(__proto__)來(lái)聯(lián)系的。

二. 原型指向

原型指向是否可以改變?——可以

構(gòu)造函數(shù)中的this就是實(shí)例對(duì)象
原型對(duì)象的方法中的this就是實(shí)例對(duì)象

1.原型指向的改變:
實(shí)例對(duì)象的原型__proto__指向的是該對(duì)象所在的構(gòu)造函數(shù)的原型對(duì)象prototype,構(gòu)造函數(shù)的的原型對(duì)象prototype指向如果改變了,實(shí)例對(duì)象的原型__proto__之象也會(huì)改變。

stu可以調(diào)用eat(),不可以調(diào)用sayHi()

原型的指向是可以改變的
實(shí)例對(duì)象和原型對(duì)象之間的關(guān)系是通過(guò)__proto__原型來(lái)聯(lián)系起來(lái)的,這個(gè)關(guān)系就是原型鏈。

2.原型的最終指向

實(shí)例對(duì)象中有__proto__原型
構(gòu)造函數(shù)中有prototype原型
prototype是對(duì)象,所以prototype對(duì)象也有__proto__---->指向哪里?

實(shí)例對(duì)象中的__proto__----->構(gòu)造函數(shù)的prototype
所以,prototype這個(gè)對(duì)象的__proto__之鄉(xiāng)的應(yīng)該是某個(gè)構(gòu)造函數(shù)的原型prototype。

以這個(gè)代碼為例:

function Person() {}Person.prototype.eat=function () {console.log("吃東西");};var per=new Person();console.dir(per);console.dir(Person);

stu.proto----->Person.prototype
Person.prototype.proto----->Object.prototype
Object.prototype.proto------>null

3.原型指向改變?nèi)绾翁砑臃椒?#xff1f;

原型改變指向有兩種順序:
①先方法后指向

原型指向改變,不再指向含有sayHi()的原型,所以無(wú)法訪問(wèn)sayHi()

②先改指向后添方法

由于先改變指向,再添加方法,所以sayHi()添加到了改變指向后的“實(shí)例對(duì)象”中。

先改變指向后添加方法可以訪問(wèn)到相應(yīng)的方法

4.實(shí)例對(duì)象和原型對(duì)象屬性重名問(wèn)題

function Person(age,sex) {this.age=age;this.sex=sex;}Person.prototype.sex="女";var per=new Person(10,"男");console.log(per.sex);//男

實(shí)例對(duì)象訪問(wèn)sex屬性,應(yīng)該先從實(shí)例對(duì)象中找,找到了直接用,找不到的時(shí)候就去指向的原型對(duì)象中找,找到了就使用,找不到…?

console.log(per.fdsfdsfsdfds);//undefined

因?yàn)镴S是一門(mén)動(dòng)態(tài)語(yǔ)言,當(dāng)一個(gè)對(duì)象沒(méi)有一個(gè)東西時(shí)時(shí),只要點(diǎn)了,那么這個(gè)對(duì)象就有了這個(gè)東西;當(dāng)沒(méi)有這個(gè)屬性時(shí),只要對(duì)象.屬性名字,對(duì)象就有這個(gè)屬性了,但是,該屬性沒(méi)有賦值,所以,結(jié)果是:undefined

console.log(fsdfdsfds);//報(bào)錯(cuò)

沒(méi)有fsdfdsfds這么變量

5.一個(gè)指向的例子

<div id="dv"></div> <script>var divObj=document.getElementById("dv");console.dir(divObj);</script>

我們可以看到div的結(jié)構(gòu),然后查看他的指向

divObj.proto---->HTMLDivElement.prototype的__proto__—>HTMLElement.prototype的__proto__---->Element.prototype的__proto__---->Node.prototype的__proto__---->EventTarget.prototype的__proto__---->Object.prototype沒(méi)有__proto__,所以,Object.prototype中的__proto__是null

繼承

面向?qū)ο缶幊趟枷?#xff1a;
??????根據(jù)需求,分析對(duì)象,找到對(duì)象的特征和行為,通過(guò)代碼的形式實(shí)現(xiàn)需求,要想實(shí)現(xiàn)需求,就要?jiǎng)?chuàng)建對(duì)象:構(gòu)造函數(shù)------創(chuàng)建對(duì)象,通過(guò)調(diào)用屬性和方法來(lái)實(shí)現(xiàn)相應(yīng)的功能及需求。

JS不是面向?qū)ο笳Z(yǔ)言,而是基于對(duì)象的語(yǔ)言。-------為什么學(xué)習(xí)面向?qū)ο?#xff1f;
??????面向?qū)ο笏枷敫m合人的思想,編程起來(lái)更加的方便,及后期的維護(hù)。

面向?qū)ο蟮奶卣?#xff1a;

  • 封裝:就是包裝
    一個(gè)值存儲(chǔ)再一個(gè)變量中------封裝
    一段重復(fù)代碼放在一個(gè)函數(shù)中-------封裝
  • 多態(tài)
    一個(gè)對(duì)象有不同的行為,或者是同一個(gè)行為針對(duì)不同的對(duì)象,產(chǎn)生不同的結(jié)果
    要想有多態(tài),就要有繼承,JS可以模擬多態(tài),但是不會(huì)使用
  • 繼承
    是一種關(guān)系,類與類之間的關(guān)系,JS通過(guò)構(gòu)造函數(shù)模擬類,通過(guò)原型實(shí)現(xiàn)繼承
    繼承是為了多態(tài)服務(wù),JS的繼承也是為了實(shí)現(xiàn)數(shù)據(jù)共享。

原型的作用:

  • 數(shù)據(jù)共享,節(jié)省內(nèi)存空間
  • 為了實(shí)現(xiàn)繼承

繼承是一種關(guān)系,父類級(jí)別和類級(jí)別的關(guān)系。

1.改變?cè)椭赶?#xff1a;

Student.prototype=new Person("小明“,10,"男");

例子:

//動(dòng)物的構(gòu)造韓素function Animal(name,weight) {this.name=name;this.weight=weight;}//動(dòng)物的原型的方法Animal.prototype.eat=function () {console.log("天天吃東西,就是吃");};//狗的構(gòu)造函數(shù)function Dog(color) {this.color=color;}Dog.prototype=new Animal("哮天犬","50kg");Dog.prototype.bitePerson=function () {console.log("哼~汪汪~(yú)咬死你");};//哈士奇function ErHa(sex) {this.sex=sex;}ErHa.prototype=new Dog("黑白色");ErHa.prototype.playHost=function () {console.log("哈哈~要壞衣服,要壞桌子,拆家..嘎嘎...好玩,開(kāi)心不,驚喜不,意外不");};var erHa=new ErHa("雄性");console.log(erHa.name,erHa.weight,erHa.color);erHa.eat();erHa.bitePerson();erHa.playHost();


2.借用構(gòu)造函數(shù)

我們來(lái)看下下面的例子

function Person(name,age,sex,weight) {this.name=name;this.age=age;this.sex=sex;this.weight=weight;}Person.prototype.sayHi=function () {console.log("您好");};function Student(score) {this.score=score;}//希望人的類別中的數(shù)據(jù)可以共享給學(xué)生---繼承Student.prototype=new Person("小明",10,"男","50kg");var stu1=new Student("100");console.log(stu1.name,stu1.age,stu1.sex,stu1.weight,stu1.score);stu1.sayHi();

以上代碼實(shí)現(xiàn)了繼承,實(shí)例對(duì)象stu1繼承了Person的屬性和方法,但是,之后創(chuàng)建的所有實(shí)例對(duì)象的屬性值都是一樣的

為了數(shù)據(jù)共享,改變?cè)椭赶?#xff0c;做到了繼承
①缺陷:因?yàn)楦淖冊(cè)椭赶虻耐瑫r(shí)實(shí)現(xiàn)了繼承,直接初始化了屬性,繼承過(guò)來(lái)的屬性值都是一樣的--------問(wèn)題
重新調(diào)用對(duì)象的屬性進(jìn)行賦值可以解決這個(gè)問(wèn)題,但是這樣會(huì)增加代碼,太過(guò)繁瑣。

var stu2=new Student("120");stu2.name="張三";stu2.age=20;stu2.sex="女";console.log(stu2.name,stu2.age,stu2.sex,stu2.weight,stu2.score);stu2.sayHi();var stu3=new Student("130");console.log(stu3.name,stu3.age,stu3.sex,stu3.weight,stu3.score);stu3.sayHi();

②解決方案:繼承的時(shí)候,不用改變?cè)偷闹赶?#xff0c;直接調(diào)用父級(jí)的構(gòu)造函數(shù)的方式來(lái)為屬性賦值--------借用構(gòu)造函數(shù)(把要繼承的父級(jí)的構(gòu)造函數(shù)拿出來(lái),使用一下)

function Person(name, age, sex, weight) {this.name = name;this.age = age;this.sex = sex;this.weight = weight;}Person.prototype.sayHi = function () {console.log("您好");};function Student(name,age,sex,weight,score) {//借用構(gòu)造函數(shù)Person.call(this,name,age,sex,weight);this.score = score;}var stu1 = new Student("小明",10,"男","10kg","100");console.log(stu1.name, stu1.age, stu1.sex, stu1.weight, stu1.score);var stu2 = new Student("小紅",20,"女","20kg","120");console.log(stu2.name, stu2.age, stu2.sex, stu2.weight, stu2.score);var stu3 = new Student("小麗",30,"妖","30kg","130");console.log(stu3.name, stu3.age, stu3.sex, stu3.weight, stu3.score);


借用構(gòu)造函數(shù):

  • 構(gòu)造函數(shù)名字.call(當(dāng)前對(duì)象,屬性1,屬性2…)
  • 解決屬性繼承,并且值不重復(fù)的問(wèn)題;
  • 缺陷:父級(jí)類別中的方法不能繼承。

3.組合繼承
為了解決借用構(gòu)造函數(shù)實(shí)現(xiàn)繼承所帶來(lái)的問(wèn)題(父級(jí)類別中的方法不能繼承),我們采用組合繼承來(lái)實(shí)現(xiàn)繼承---------原型繼承+借用構(gòu)造函數(shù)繼承。

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) {//借用構(gòu)造函數(shù):屬性值重復(fù)的問(wèn)題Person.call(this,name,age,sex);this.score=score;}//改變?cè)椭赶?---繼承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.拷貝繼承
拷貝繼承:把一個(gè)對(duì)象中的屬性或者方法直接復(fù)制到另一個(gè)對(duì)象中

  • var obj1=obj2;
  • var obj1={name:"小糊涂",age:20,sleep:function () {console.log("睡覺(jué)了");}};//改變了地址的指向var obj2=obj1;console.log(obj2.name,obj2.age);obj2.sleep();
  • 淺拷貝
  • var obj1={name:"小糊涂",age:20,sleep:function () {console.log("睡覺(jué)了");}};var obj2={};for(var key in obj1){obj2[key]=obj1[key];}console.log(obj2.name);
  • function Person() {}Person.prototype.age=10;Person.prototype.sex="男";Person.prototype.height=100;Person.prototype.play=function () {console.log("玩的好開(kāi)心");};var obj2={};//Person的構(gòu)造中有原型prototype,prototype就是一個(gè)對(duì)象,那么里面,age,sex,height,play都是該對(duì)象中的屬性或者方法for(var key in Person.prototype){obj2[key]=Person.prototype[key];}console.dir(obj2);obj2.play();

    5.繼承的總結(jié)

    • 面向?qū)ο蟮奶匦?#xff1a;封裝、繼承、多態(tài)
    • 繼承:類與類之間的關(guān)系,面向?qū)ο笳Z(yǔ)言的繼承是為了多態(tài)服務(wù)的。JS不是面向?qū)ο笳Z(yǔ)言,但是可以模擬面向?qū)ο?#xff0c;模擬繼承,為了節(jié)省空間。
    • 繼承
      ①原型作用:數(shù)據(jù)共享;目的:節(jié)省空間
      ??????????????????????繼承;目的:節(jié)省空間
      ②原型繼承:改變?cè)椭赶?br /> ③借用構(gòu)造函數(shù)繼承:主要解決屬性值相同的問(wèn)題(Person.call(this,name,age))
      ④組合繼承:原型繼承+借用構(gòu)造函數(shù)繼承
      ??????????????????????既能解決屬性值相等的問(wèn)題,又能解決父級(jí)方法調(diào)用問(wèn)題
      ⑤拷貝繼承:就是把對(duì)象中需要共享的屬性或者方法,直接遍歷的方式復(fù)制
      ??????????????????????到另一個(gè)對(duì)象中

    其他知識(shí)點(diǎn)

    1.逆推繼承看原型

    function F1(age) {this.age = age;}function F2(age) {this.age = age;}F2.prototype = new F1(10);function F3(age) {this.age = age;}F3.prototype = new F2(20);var f3 = new F3(30);console.log(f3.age);//30


    f3.age先在實(shí)例對(duì)象中查找,若找不到,則逐級(jí)向上查找(原型中),假若原型中也沒(méi)有,為undefined

    2.函數(shù)角色
    函數(shù)角色:函數(shù)聲明、函數(shù)表達(dá)式

    • 函數(shù)聲明
    function f1() {console.log("我是函數(shù)");}f1();
    • 函數(shù)表達(dá)式
    var ff=function () {console.log("我也是一個(gè)函數(shù)");};ff();
    • 函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別
    //函數(shù)聲明if(true){function f1() {console.log("哈哈,我又變帥了");}}else{function f1() {console.log("小蘇好猥瑣");}}f1();//哈哈,我又變帥了//在IE8下結(jié)果為:小蘇好猥瑣 //函數(shù)表達(dá)式var ff;if(true){ff=function () {console.log("哈哈,我又變帥了");};}else{ff=function () {console.log("小蘇好猥瑣");};}ff();//哈哈,我又變帥了

    函數(shù)聲明如果放在if-else語(yǔ)句中,在IE8的瀏覽器中會(huì)出現(xiàn)問(wèn)題;函數(shù)表達(dá)式則不會(huì)出現(xiàn)問(wèn)題。

    3.函數(shù)中this指向問(wèn)題

    • 普通函數(shù)中的this-------window
    • 對(duì)象方法中的this-------當(dāng)前的實(shí)例對(duì)象
    • 定時(shí)器方法中的this-------window
    • 構(gòu)造函數(shù)中的this-------實(shí)例對(duì)象
    • 原型對(duì)象中的this--------實(shí)例對(duì)象

    4.嚴(yán)格模式
    嚴(yán)格模式下,方法應(yīng)由對(duì)象調(diào)用

    //嚴(yán)格模式 "use strict" function f1() {console.log("this"); } window.f1();//嚴(yán)格模式下,不寫(xiě)window,結(jié)果為undefined

    5.函數(shù)的不同調(diào)用方法

    • 普通函數(shù)
    function f1() {console.log("文能提筆控蘿莉");}f1();
    • 構(gòu)造函數(shù)
    function F1() {console.log("我是構(gòu)造函數(shù),我驕傲");}var f=new F1();
    • 對(duì)象的方法
    function Person() {this.play=function () {console.log("玩代碼");};}var per=new Person();per.play();

    6.函數(shù)也是對(duì)象,對(duì)象不一定是函數(shù)
    對(duì)象中有__proto__原型,是對(duì)象
    函數(shù)中有prototype原型,是對(duì)象

    對(duì)象中有__proto__,函數(shù)中應(yīng)該有prototype
    如果一個(gè)東西里面有prototype,又有__proto__,說(shuō)明是函數(shù),也是對(duì)象

    所有的函數(shù)實(shí)際上都是Function的構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例對(duì)象====>函數(shù)也是對(duì)象
    Math中有__proto__,但是沒(méi)有prorotype,所以Math是對(duì)象,但不是函數(shù)====>對(duì)象不一定是函數(shù)

    7.數(shù)組中的函數(shù)調(diào)用

    數(shù)組可以存儲(chǔ)任何類型的數(shù)據(jù)

    var arr=[function () {console.log("十一假期快樂(lè)");},function () {console.log("十一假期開(kāi)心");},function () {console.log("十一假期健康");},function () {console.log("十一假期安全");},function () {console.log("十一假期如意");}];//回調(diào)函數(shù):函數(shù)作為參數(shù)使用arr.forEach(function(ele){ele();});

    forEach() 方法用于調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)。
    注意: forEach() 對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的。
    array.forEach(function(currentValue, index, arr), thisValue)

    總結(jié)

    以上是生活随笔為你收集整理的JavaScript高级学习(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。