Js進(jìn)階

面向過(guò)程POP

Javascript進(jìn)階

面向過(guò)程POP

? (process-oriented programming)分析出解決問(wèn)題所需的步驟,然后用函數(shù)把這些步驟一步一步實(shí)現(xiàn),使用的時(shí)候再一個(gè)一個(gè)的依次調(diào)用就可以了

面向?qū)ο驩OP

(object oriented programming)把事務(wù)分解成一個(gè)個(gè)對(duì)象,然后由對(duì)象之間分工合作。

OOP的特性:封裝性,繼承性,多態(tài)性

對(duì)象是一組無(wú)序的相關(guān)屬性和方法的集合。

【類class】

創(chuàng)建類? class name {

? ? ? ? ? }

創(chuàng)建實(shí)例? var xx = name(); 類必須使用new實(shí)例化對(duì)象

類constructor構(gòu)造函數(shù)

constructor()方法是類的構(gòu)造函數(shù)(默認(rèn)的方法),用于傳遞參數(shù),返回實(shí)例對(duì)象,通過(guò)new命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法,如果沒(méi)有顯示定義,類內(nèi)部會(huì)自動(dòng)給我們創(chuàng)建一個(gè)constructor()

語(yǔ)法:

class Person {

? ? constructor (name,age) {? //構(gòu)造方法或構(gòu)造函數(shù)

? ? ? ? ? this.name = name;

? ? ? ? ? this.age = age;

? ? }

? ? say () {

? ? }

}

var ldh = new Person('劉德華',18);

繼承extends

class Father {

}

class Son extends Father {

}

【super】關(guān)鍵字-訪問(wèn)和調(diào)用對(duì)象父類上的函數(shù)

class Person {

? ? constructor (surname) {

? ? ? this.surname = surname;

? }

}

class Student extends Person { //子類繼承父類

? ? constructor (surname,firstname) {

? ? ? super(surname);? // 調(diào)用父類的constructor(surname)

? ? ? ? this.firstname = firstname;//定義子類獨(dú)有的屬性

? ? }

}

注意:super必須放到this前面?

super用于訪問(wèn)和調(diào)用對(duì)象父類上的函數(shù),可以調(diào)用父類的構(gòu)造函數(shù),也可以調(diào)用父類的普通函數(shù)

在ES6中類沒(méi)有變量提升,所以必須先定義類,才能通過(guò)類實(shí)例化對(duì)象。

類里面的共有屬性和方法一定要加this使用。

類里面的this指向問(wèn)題。

constructor 里面的this指向?qū)嵗龑?duì)象,方法里面的this指向這個(gè)方法的調(diào)用者。

insertAdjacentHTML(追加的位置,'要追加的字符串元素')-可以直接把字符串格式的元素添加到父元素中。不可以用appendChild追加。

追加的位置-beforeend插入元素內(nèi)部的最后一個(gè)子節(jié)點(diǎn)之后。

禁止選中文字

window.getSelection?window.getSelection().removeAllRanges() : document.selection.empty();

構(gòu)造函數(shù)-一種特殊的函數(shù),主要用來(lái)初始化對(duì)象,即為對(duì)象成員變量賦初始值,它總與new一起使用,我們可以把對(duì)象中一些公共的屬性和方法抽取出來(lái),然后封裝到這個(gè)函數(shù)里面。

在Js中使用構(gòu)造函數(shù)時(shí)需要注意以下兩點(diǎn)∶

構(gòu)造函數(shù)用于創(chuàng)建某一類對(duì)象,其首字母要大寫。構(gòu)造函數(shù)要和new一起使用才有意義。

new在執(zhí)行時(shí)會(huì)做四件事:

在內(nèi)存中創(chuàng)建一個(gè)新的空對(duì)象。

讓this指向這個(gè)新的對(duì)象。

執(zhí)行構(gòu)造函數(shù)里面的代碼,給這個(gè)新對(duì)象添加屬性方法。

返回這個(gè)新對(duì)象(所以構(gòu)造函數(shù)里面不需要return)

構(gòu)造函數(shù)可以添加一些成員,可以在構(gòu)造函數(shù)本身上添加,也可以在構(gòu)造函數(shù)內(nèi)部的this上添加。通過(guò)這兩種方法添加的成員分別稱為靜態(tài)成員和實(shí)例成員。

靜態(tài)成員:在構(gòu)造函數(shù)本身上添加的成員,只能由構(gòu)造函數(shù)本身來(lái)訪問(wèn)。

實(shí)例成員:在構(gòu)造函數(shù)內(nèi)部創(chuàng)建的對(duì)象成員,只能由實(shí)例化的對(duì)象來(lái)訪問(wèn)。

構(gòu)造函數(shù)原型prototype

構(gòu)造函數(shù)通過(guò)原型分配的函數(shù)是所有對(duì)象所共享的,js規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype 屬性,指向另一個(gè)對(duì)象。注意這個(gè)prototype就是一個(gè)對(duì)象,這個(gè)對(duì)象的所有方法和屬性,都會(huì)被構(gòu)造函數(shù)所擁有。我們可以把那些不變的方法直接定義在prototype對(duì)象上,這樣所有對(duì)象的實(shí)例就可以共享這些方法。

原型是什么-一個(gè)對(duì)象,我們也稱為prototype為原型對(duì)象。作用是共享方法。

function Star (uname,age) {

? ? this.uname = unane;

? ? this.age = age;

}

Star.prototype.sing = function (){

}//在原型上添加共有方法

對(duì)象原型__proto__

對(duì)象都會(huì)有一個(gè)屬性__proto__指向構(gòu)造函數(shù)的prototype 原型對(duì)象,之所以我們對(duì)象可以使用構(gòu)造函數(shù)函數(shù)prototype原型對(duì)象的方法,就因?yàn)閷?duì)象有__proto__原型存在。

__proto__對(duì)象原型和原型對(duì)象prototype是等價(jià)的,

__proto__對(duì)象原型的意義就在于為對(duì)象的查找機(jī)制提供一個(gè)方向,或者說(shuō)一條線,但是它是一個(gè)非標(biāo)準(zhǔn)屬性,因此實(shí)例開(kāi)發(fā)中,不可以使用這個(gè)屬性,它只是內(nèi)部指向原型對(duì)象prototype.

三者之間關(guān)系

Star構(gòu)造函數(shù)通過(guò)Star.prototype指向Star原型對(duì)象prototype

Star原型對(duì)象prototype通過(guò)原型對(duì)象.constructor指向Star構(gòu)造函數(shù)

Star構(gòu)造函數(shù)直接指向它的ldh實(shí)例化對(duì)象

ldh對(duì)象實(shí)例通過(guò)ldh.__proto__指向Star原型對(duì)象prototype

__proto__和prototype里面都有一個(gè)constructor 屬性,constructor我們稱為構(gòu)造函數(shù),因?yàn)樗赶驑?gòu)造函數(shù)本身。

constructor主要用于記錄該對(duì)象引用于哪個(gè)構(gòu)造函數(shù),它可以讓原型對(duì)象重新指向原來(lái)的構(gòu)造函數(shù)。

JS查找機(jī)制

先查找自身屬性-再查找原型-查找對(duì)象的原型Object 的原型-null

__proto__的意義就在于為對(duì)象成員查找提供一個(gè)方向,或者說(shuō)一條路線。

原型對(duì)象this指向

構(gòu)造函數(shù)里的this指向?qū)嵗龑?duì)象。

原型對(duì)象里面放的是方法,這個(gè)方法里面的this指向的是這個(gè)方法的調(diào)用者,也就是這個(gè)實(shí)例對(duì)象。

通過(guò)原型對(duì)象,對(duì)原來(lái)的內(nèi)置對(duì)象進(jìn)行擴(kuò)展自定義的方法。

繼承【繼承】

ES6之前沒(méi)有給我們提供extends繼承,我們可以通過(guò)構(gòu)造函數(shù)+原型對(duì)象模擬實(shí)現(xiàn)繼承,也就是組合繼承。

call()方法

fun.call(thisArg,arg1,arg2...)

thisArg:當(dāng)前調(diào)用函數(shù)this的指向?qū)ο?/p>

arg1:傳遞的其他參數(shù)

借用構(gòu)造函數(shù)繼承父類型屬性

核心原理:通過(guò)call()把父類型的this指向子類型的this,這樣就可以實(shí)現(xiàn)子類型的屬性。

function Father (name,age) {

? ? this.name=name;

? ? this.age=age;

}

function Son (name,age,sex) {

? ? Father.call(this,name,age);//父類的this指向子類的this,.同時(shí)調(diào)用這個(gè)函數(shù)

? ? this.sex=sex;

}

var xt= new Son('ez','18','男');

借用原型對(duì)象繼承父類型方法

一般情況下,對(duì)象的方法都在構(gòu)造函數(shù)的原型對(duì)象中設(shè)置,通過(guò)構(gòu)造函數(shù)無(wú)法繼承父類方法。核心原理-

將子類所共享的方法提取出來(lái),讓子類的prototype原型對(duì)象=new 父類(),

本質(zhì)-子類原型對(duì)象等于是實(shí)例化父類,因?yàn)楦割悓?shí)例化之后另外開(kāi)辟空間,就不會(huì)影響原來(lái)父類原型對(duì)象,將子類的constructor 重新指向子類的構(gòu)造函數(shù)。

類的本質(zhì)

class的本質(zhì)還是function

類的所有方法都定義在類的prototype屬性上

類創(chuàng)建的實(shí)例,里面也有__proto__指向類的prototype原型對(duì)象

ES6的類它的絕大部分功能,Es5都可以做到,新的class寫法只是讓對(duì)象原型的寫法更加清晰,更像面向?qū)ο缶幊痰恼Z(yǔ)法而已

ES5新增的方法

數(shù)組方法

foreach()

array.foreach(function(currentValue,index,arr){})

currentValue:數(shù)組當(dāng)前項(xiàng)的值

index:數(shù)組當(dāng)前項(xiàng)的索引號(hào)

arr:數(shù)組對(duì)象本身

arr.foreach(function(value,index,array){

//函數(shù)內(nèi)部可以獲取到參數(shù)值

? ? })

filter()篩選元素,返回新數(shù)組

array.filter(function(value,index,array){

//函數(shù)內(nèi)部可以獲取到參數(shù)值

? ? })

currentValue:數(shù)組當(dāng)前項(xiàng)的值

index:數(shù)組當(dāng)前項(xiàng)的索引號(hào)

arr:數(shù)組對(duì)象本身

返回一個(gè)新數(shù)組,新數(shù)組中的元素是通過(guò)檢查指定數(shù)組中符合條件的所有元素,主要用于篩選數(shù)組。

例子-

var arr=[12,66,4,88,3,7];

var newArr=arr.filter(function(value,index){

? return value%2===0;

});

some()查找元素,返回布爾值

array.some(function(value,index,array){

//函數(shù)內(nèi)部可以獲取到參數(shù)值

? ? })

currentValue:數(shù)組當(dāng)前項(xiàng)的值

index:數(shù)組當(dāng)前項(xiàng)的索引號(hào)

arr:數(shù)組對(duì)象本身

用于檢測(cè)數(shù)組中的元素是否滿足指定條件,查找數(shù)組中是否滿足條件的元素。

返回布爾值,如果查到這個(gè)元素就返回true,查不到返回false.

找到你一個(gè)滿足條件的元素,則終止循環(huán),不再繼續(xù)查找。

把數(shù)據(jù)渲染到頁(yè)面-foreach

根據(jù)價(jià)格顯示數(shù)據(jù)-filter

字符串方法

str.trim(),刪除字符串兩端的空白字符,不影響原字符串本身,返回新字符串,可用于用戶輸入空格失去焦點(diǎn)時(shí)清空表單。

對(duì)象方法

Object.keys(obj)用于獲取對(duì)象自身所有屬性

類似for...in

返回一個(gè)由屬性名組成的數(shù)組。

Object.defineProperty(obj,prop,descriptor)

obj-必需,目標(biāo)對(duì)象

prop-必需,需定義或修改的屬性的名字

descriptor-必需,目標(biāo)屬性所擁有的特性,以對(duì)象{}形式書寫,value:設(shè)置屬性的值,默認(rèn)undefined

writable:值是否可以重寫,true|false,默認(rèn)為false

enumerable:目標(biāo)屬性是否可以被枚舉,true|false,默認(rèn)為false

configurable:目標(biāo)屬性是否可以被刪除或是否可以再次修改特性true|false,默認(rèn)為false

定義對(duì)象中新屬性或者修改原有屬性。

改變函數(shù)內(nèi)部this指向

1.call方法

call()方法調(diào)用一個(gè)對(duì)象,簡(jiǎn)單理解為調(diào)用函數(shù)的方式,但是它可以改變函數(shù)的this指向。

fun.call(thisArg,arg1,arg2...)

thisArg:在fun函數(shù)運(yùn)行時(shí)指定的this值

arg:傳遞的其他參數(shù)

返回值就是函數(shù)的返回值,因?yàn)樗褪钦{(diào)用函數(shù)。

因此當(dāng)我們想改變this指向,同時(shí)想調(diào)用這個(gè)函數(shù),可以使用call,比如繼承

2.apply方法

fun.apply(thisArg,[argArray])

thisArg:在fun函數(shù)運(yùn)行時(shí)指定的this值

argArray:傳遞的值,必須包含在數(shù)組里面

返回值就是函數(shù)的返回值,因?yàn)樗褪钦{(diào)用函數(shù)

因此apply主要和數(shù)組有關(guān),比如使用Math.max()求數(shù)組的最大值

var arr=[1,66,3,99,4];

var max=Math.max.apply(Math,arr);

3.bind方法

fun.bind(thisArg,arg1,arg2...)

thisArg:在fun函數(shù)運(yùn)行時(shí)指定的this值

arg:傳遞的其他參數(shù)

返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝

因此當(dāng)我們只是想改變this指向,并且不想調(diào)用這個(gè)函數(shù)的時(shí)候可以使用bind

call,apply,bind總結(jié)

相同點(diǎn):改變函數(shù)內(nèi)部this指向

區(qū)別:call和apply會(huì)調(diào)用函數(shù),且改變函數(shù)內(nèi)部this指向,

call和apply傳遞參數(shù)不一樣,后者是數(shù)組形式,bind不會(huì)調(diào)用函數(shù)

應(yīng)用場(chǎng)景:call-繼承

aplly-與數(shù)組有關(guān),求最大值最小值

bind-改變定時(shí)器內(nèi)部this指向

嚴(yán)格模式

'use strict'

1.為腳本開(kāi)啟嚴(yán)格模式

(function () {

? 'use strict';

})();

2.為函數(shù)開(kāi)啟嚴(yán)格模式

嚴(yán)格模式中的變化

1.變量規(guī)定-在正常模式下,一個(gè)變量不聲明就賦值,默認(rèn)是全局變量,嚴(yán)格模式下禁止這種用法,變量必須才用var命令聲明,然后再使用。

嚴(yán)禁刪除已經(jīng)聲明的變量。例如delete x;語(yǔ)法是錯(cuò)誤的。

2.嚴(yán)格模式下this指向問(wèn)題

以往全局作用域函數(shù)中的this指向window對(duì)象。嚴(yán)格模式下全局作用域函數(shù)中的this是undefined。以前構(gòu)造函數(shù)時(shí)不加new也可以調(diào)用,當(dāng)普通函數(shù),this指向全局對(duì)象。嚴(yán)格模式下,如果構(gòu)造函數(shù)不加new調(diào)用,this指向的是undefined,如果給他賦值則會(huì)報(bào)錯(cuò)。

new實(shí)例化的構(gòu)造函數(shù)指向創(chuàng)建的對(duì)象實(shí)例。

定時(shí)器this還是指向window。事件、對(duì)象還是指向調(diào)用者。

3.函數(shù)變化

函數(shù)不能有重名參數(shù)。

函數(shù)必須聲明在頂層,新版本js會(huì)引入塊級(jí)作用域,為了與新版本接軌,不允許在非函數(shù)的代碼塊內(nèi)聲明函數(shù)。

高階函數(shù):是對(duì)其他函數(shù)進(jìn)行操作的函數(shù),它接收函數(shù)作為參數(shù)或?qū)⒑瘮?shù)作為返回值輸出。

閉包:有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù)。就是一個(gè)作用域可以訪問(wèn)另一個(gè)函數(shù)內(nèi)部的局部變量。

閉包的作用-延伸變量的作用范圍。

閉包案例:打車價(jià)格

遞歸,一個(gè)函數(shù)在內(nèi)部調(diào)用其本身,那個(gè)這個(gè)函數(shù)就是遞歸函數(shù)。遞歸函數(shù)的作用和循環(huán)效果一樣。遞歸容易發(fā)生棧溢出,所以必須要加return退出條件。

遞歸案例:

求1-n的階乘

求斐波那契數(shù)列

function fb(n) {

? if( n===1 || n=== 2){

? ? ? return 1;

}

return fb(n-1)+fb(n-2);

}

根據(jù)id返回對(duì)應(yīng)的數(shù)據(jù)對(duì)象。

淺拷貝只拷貝一層,更深層次對(duì)象級(jí)別的只拷貝引用。

深拷貝拷貝多層,每一級(jí)別的數(shù)據(jù)都會(huì)拷貝。

Object.assign(target,...sources) es6新增方法可以淺拷貝

深拷貝封裝

function deepCopy(newobj,oldobj) {

? ? for(var k in oldobj){

? ? ? ? var item = oldobj[k];

? ? ? ? if (item instanceof Array) {

? ? ? ? ? ? newobj[k] = [];

? ? ? ? ? ? deepCopy(newobj[k],item);

? ? ? ? } else if (item instanceof Object){

? ? ? ? ? ? newobj[k] = {};

? ? ? ? ? ? deepCopy(newobj[k],item);

? ? ? ? } else {

? ? ? ? ? ? newobj[k] = item;

? ? ? ? }

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容