日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

JavaScript学习记录十六

發布時間:2023/12/18 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript学习记录十六 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原型鏈的引入

??? //如果想要使用一些屬性和方法,并且屬性的值在每個對象中都是一樣的,方法在每個對象中的操作也都是一樣,

??? //那么,為了共享數據,節省內存空間,是可以把屬性和方法通過原型的方式進行賦值

??? //實例對象的原型__proto__和構造函數的原型prototype指向是相同的

??? //實例對象中的__proto__原型指向的是構造函數中的原型prototype

??? //實例對象中__proto__是原型,瀏覽器使用的
??? //構造函數中的prototype是原型,程序員使用的

??? //原型鏈:是一種關系,實例對象和原型對象之間的關系,關系是通過原型(__proto__)來聯系的

console.log(per.__proto__==Person.prototype); true

??? //構造函數中的this就是實例對象
??? //原型對象中方法中的this就是實例對象

??? ↓三處的打印是相同的

<script>function Person(age) {this.age=age;console.log(this);}Person.prototype.eat=function () {console.log(this);};var per=new Person(10);console.log(per); </script>

__proto__指向分析

??? //實例對象中有__proto__原型
??? //構造函數中有prototype原型
??? //prototype是對象
??? //所以,prototype這個對象中也有__proto__,那么指向了哪里
??? //實例對象中的__proto__指向的是構造函數的prototype
??? //所以,prototype這個對象中__proto__指向的應該是某個構造函數的原型prototype

??? //per實例對象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是null

<script>function Person(age) {this.age=age;}var per=new Person(10);console.log(Person.prototype.__proto__==Object.prototype);//trueconsole.log(Object.prototype.__proto__); null </script>

原型的指向改變,添加原型方法需要在原型改變之后

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();</script>

實例對象和原型對象的屬性分析

??? //因為JS是一門動態類型的語言,對象沒有什么,只要點了,那么這個對象就有了這個東西,沒有這個屬性,只要對象.屬性名字,對象就有這個屬性了,但是,該屬性沒有賦值,所以,結果是:undefined
????? console.log(per.fdsfdsfsdfds);? undefined

??? //實例對象訪問這個屬性,應該先從實例對象中找,找到了就直接用,找不到就去指向的原型對象中找,找到了就使用,找不到呢?=====
??? //通過實例對象能否改變原型對象中的屬性值?不能
??? //就想改變原型對象中屬性的值,怎么辦?直接通過原型對象.屬性=值;可以改變

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

有趣的原型鏈

??? //原型鏈:實例對象和原型對象之間的關系,通過__proto__來聯系

? ↓ 以下是普通的div標簽的原型鏈指向

??? divObj.__proto__---->HTMLDivElement.prototype的__proto__

??? --->HTMLElement.prototype的__proto__---->Element.prototype的__proto__

??? ---->Node.prototype的__proto__---->EventTarget.prototype的__proto__

??? ---->Object.prototype沒有__proto__,所以,Object.prototype中的__proto__是null

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>title</title><script>原型鏈:實例對象和原型對象之間的關系,通過__proto__來聯系</script> </head> <body> <div id="dv"></div> <script>var divObj=document.getElementById("dv");console.dir(divObj); </script> </body> </html>

繼承

??? * 面向對象編程思想:根據需求,分析對象,找到對象有什么特征和行為,通過代碼的方式來實現需求,要想實現這個需求,就要創建對象,要 想創建對象,就應該顯示有構造函數,然后通過構造函數來創建對象.,通過對象調用屬性和方法來實現相應的功能及需求,即可
??? * 首先JS不是一門面向對象的語言,JS是一門基于對象的語言,那么為什么學習js還要學習面向對象,因為面向對象的思想適合于人的想法,編程起來會更加的方便,及后期的維護....
??? * 面向對象的編程語言中有類(class)的概念(也是一種特殊的數據類型),但是JS不是面向對象的語言,所以,JS中沒有類(class),但是JS可以模擬面向對象的思想編程,JS中會通過構造函數來模擬類的概念(class)

??? * 共同的特征和行為
??? * 特征--->屬性
??? * 行為---方法
??? *
??? * 面向對象的特性:封裝,繼承,多態
??? *
??? * 封裝:就是包裝
??? * 一個值存儲在一個變量中--封裝
??? * 一坨重復代碼放在一個函數中--封裝
??? * 一系列的屬性放在一個對象中--封裝
??? * 一些功能類似的函數(方法)放在一個對象中--封裝
??? * 好多相類似的對象放在一個js文件中---封裝
??? *
??? * 繼承: 首先繼承是一種關系,類(class)與類之間的關系,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();

借用構造函數

??? //為了數據共享,改變原型指向,做到了繼承---通過改變原型指向實現的繼承

??? //缺陷:因為改變原型指向的同時實現繼承,直接初始化了屬性,繼承過來的屬性的值都是一樣的了,所以,這就是問題

??? //解決方案:繼承的時候,不用改變原型的指向,直接調用父級的構造函數的方式來為屬性賦值就可以了------借用構造函數:把要繼承的父級的構造函數拿過來,使用一下就可以了

??? //借用構造函數:構造函數名字.call(當前對象,屬性,屬性,屬性....);
??? //解決了屬性繼承,并且值不重復的問題
??? //缺陷:父級類別中的方法不能繼承

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) {//借用構造函數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);小明 10 男 10kg 100

組合繼承

//原型實現繼承 //借用構造函數實現繼承 //組合繼承:原型繼承+借用構造函數繼承 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);小黑 20 男 100分stu.sayHi();阿涅哈斯誒呦stu.eat();吃東西

拷貝繼承

var p={name:'wutong',age:12};var p1={};for(var key in p){p1[key]=p[key];}console.dir(p1);console.log(p==p1);//falsefunction Person() {}Person.prototype.name='zhangsan';Person.prototype.age=12;var p2=new Person();for(var key in Person.prototype){p2[key]=Person.prototype[key];}console.dir(p2)

繼承總結

??? //繼承,類與類之間的關系,面向對象的語言的繼承是為了多態服務的,
??? //js不是面向對象的語言,但是可以模擬面向對象.模擬繼承.為了節省內存空間

??? //繼承:
??? /*
??? * 原型作用: 數據共享 ,目的是:為了節省內存空間,
??? * 原型作用: 繼承? 目的是:為了節省內存空間
??? *
??? * 原型繼承:改變原型的指向
??? * 借用構造函數繼承:主要解決屬性的問題
??? * 組合繼承:原型繼承+借用構造函數繼承
??? * 既能解決屬性問題,又能解決方法問題
??? * 拷貝繼承:就是把對象中需要共享的屬性或者犯法,直接遍歷的方式復制到另一個對象中

逆序繼承看原型

???? *理解:通過原型實現了繼承,所以子初始化的時候必須調用改變的原型指向的初始化。

???? *f3? age=30? → f3.__proto__.age=20 (f1)? →? f1.__proto__.age=10;

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

函數的聲明和函數表達式

函數的聲明function f1() {console.log("我是函數");}f1();函數表達式var ff=function () {console.log("我也是一個函數");};ff();

函數聲明和函數表達式的區別

??? //函數聲明如果放在if-else的語句中,在IE8的瀏覽器中會出現問題,函數聲明在if-else塊中,塊外無法實現調用
??? //以后寧愿用函數表達式,都不用函數聲明

?

if(true){function f1() {console.log("哈哈,我又變帥了");}}else{function f1() {console.log("小蘇好猥瑣");}}f1();var ff;if(true){ff=function () {console.log("哈哈,我又變帥了");};}else{ff=function () {console.log("小蘇好猥瑣");};}ff();

函數中的this的指向
???? * 普通函數中的this是誰?-----window
???? * 對象.方法中的this是誰?----當前的實例對象
???? * 定時器方法中的this是誰?----window
???? * 構造函數中的this是誰?-----實例對象
???? * 原型對象方法中的this是誰?---實例對象

<script>"use strict";//嚴格模式function f1() {console.log(this);undefined}f1();function f1() {console.log(this); window}f1();var timeId=setInterval(function () {console.log(this); windowclearInterval(timeId);},1000);function Person() {console.log(this);Person{}this.sayHi=function () {console.log(this); Person{sayHi}};}Person.prototype.eat=function () {console.log(this); Person{sayHi}};var per=new Person();console.log(per); Person{sayHi}per.sayHi();per.eat();</script>

普通函數和構造函數

?? *語法上只有大小寫的區分,使用上構造函數通過new來實現調用,普通函數直接調用即可

普通函數function f1() {console.log("文能提筆控蘿莉");}f1();構造函數---通過new 來調用,創建對象function F1() {console.log("我是構造函數,我驕傲");}var f=new F1();

區分函數和對象

??? //函數是對象,對象不一定是函數

??? //對象中有__proto__原型,是對象
??? //函數中有prototype原型,是對象

?? //如果一個東西里面有prototype,又有__proto__,說明是函數,也是對象

對象中有__proto__,函數中應該有prototypeconsole.dir(Math); 中有__proto__,但是沒有prorotype

數組中函數的調用

?? *javascript是弱類型語言,所以數組中可以存放各種數據類型,但是為了方便遍歷,盡量存放同種類型

<script>var arr=[function () {console.log('hello world!')},function () {console.log('hello world!')}];arr.forEach(function (ele) {ele();})</script>

?

總結

以上是生活随笔為你收集整理的JavaScript学习记录十六的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。