一天一個js知識

原型繼承和class繼承

class:js中并不存在類的概念,class只是語法糖,本質還是函數;

提升&暫時性死區

console.log(a)// ? a() {}
var a=8
function a(){}
復制代碼

1、這里說明函數的提升要優先于變量的提升;函數提升會把整個函數挪到作用域頂部,變量提升只會把聲明挪到作用域頂部

2、如果把函數代碼刪掉,把var變成let,則會報錯a is not defined這時候的報錯則是因為暫時性死區的原因導致,我們不能在聲明前就使用變量;

疑問:為什要有提升這個東西? 存在原因:其實提升存在的根本原因就是為了解決函數間互相調用的情況

原型

每個對象當我們打印的時候下面都會有個__proto__屬性,該屬性指向了原型,原型也是一個對象,且這個對象包含了很多的函數,還有一個 constructor屬性,也就是構造函數,打開 constructor 屬性我們又可以發現其中還有一個 prototype 屬性,并且這個屬性對應的值和先前我們在 proto 中看到的一模一樣。所以我們又可以得出一個結論:原型的 constructor 屬性指向構造函數,構造函數又通過 prototype 屬性指回原型,但是并不是所有函數都具有這個屬性,Function.prototype.bind() 就沒有這個屬性。

總結: Object 是所有對象的爸爸,所有對象都可以通過 proto 找到它 Function 是所有函數的爸爸,所有函數都可以通過 proto 找到它 函數的 prototype 是一個對象 對象的 proto 屬性指向原型, proto 將對象和原型連接起來組成了原型鏈

淺拷貝&&深拷貝

淺拷貝:

1、const obj=Object.assign(target,...sources)將sources對象的所有屬性值拷貝到target對象上,實現的是淺拷貝,改變sources的屬性值,obj不會發生改變

2、通過展開運算符 ... 來實現淺拷貝

let b={...a}
//這時改變a的屬性值b也不會改變
復制代碼

淺拷貝只解決了第一層的問題,如果目標對象的值中還有對象的話,那么就又回到最開始的話題了,兩者享有相同的地址。要解決這個問題,我們就得使用深拷貝了。

深拷貝: 1、通過 JSON.parse(JSON.stringify(object)) 來實現深拷貝

let b = JSON.parse(JSON.stringify(a))
復制代碼

但是此方法會忽略 undefined和symbol、不能序列化函數、不能解決循環引用的對象

2、使用new MessageChannel()

function structuralClone(obj) {return new Promise(resolve => {const { port1, port2 } = new MessageChannel()port2.onmessage = ev => resolve(ev.data)port1.postMessage(obj)})
}var obj = {a: 1,b: {c: 2}
}obj.b.d = obj.b// 注意該方法是異步的
// 可以處理 undefined 和循環引用對象
const test = async () => {const clone = await structuralClone(obj)console.log(clone)
}
test()
復制代碼

bind(),call(), apply()

前面講到了this指向 那么這次就說說改變this指向的三個方法

bind方法是用于創建一個函數,使這個函數不論怎么調用都有同樣的this,該方法返回一個新函數,你必須調用它才會生效,參數跟call一樣第一個是this,參數是直接放進去的,第二第三第n個參數全都用逗號分隔,直接放到后面

call與bind的區別就是它返回的是一個執行結果不需要調用

apply它與call的區別是第二個參數接受的是一個數組

以上三個的參數都沒有限制可以是各種類型

bind()函數內部怎么實現的:

Function.prototype.myBind=function(context){if(typeof this!=='function'){throw new TypeError('err')}const _this=thisconst args=[...arguments].slice(1)//返回一個函數return F(){//最后來說通過 new 的方式,在之前的章節中我們學習過如何判斷 //this,對于 new 的情況來說,不會被任何方式改變 //this,所以對于這種情況我們需要忽略傳入的 thisif(this instanceof F){return new _this(...args,...arguments)}//對于直接調用來說,這里選擇了 apply //的方式實現,但是對于參數需要注意以下情況:因為 bind //可以實現類似這樣的代碼 f.bind(obj, //1)(2),所以我們需要將兩邊的參數拼接起來,于是就有了這樣的實現 //args.concat(...arguments)return _this.apply(context,args.concat(...arguments))}
}
復制代碼

call()函數內部怎么實現的:

Function.prototype().myCall=function(context){if(typeoof this!=='function'){throw new TypeError('err')}context=context||window //context是可選參數,不傳默認windowcontext.fn=this //給context創建fn屬性,并將值設置為需要調用的函數const args=[...arguments].slice(1)//因為call可以傳入多個參數,需要將參數剝離出來const resule=context.fn(...args)//調用函數delete context.fn//調用完后刪除對象上的函數return result
}
復制代碼

apply()函數內部怎么實現的:

Function.prototype.myApply = function(context) {if (typeof this !== 'function') {throw new TypeError('Error')}context = context || windowcontext.fn = thislet result// 處理參數和 call 有區別if (arguments[1]) {result = context.fn(...arguments[1])} else {result = context.fn()}delete context.fnreturn result
}
復制代碼

this指向

對于this指向很多人都會混淆,其實很多網上把它說負復雜了看以下場景:

function foo(){console.log(this)
}
foo()
let num=1
const obj={num:1,foo:foo
}
obj.foo()
const c=new foo()
復制代碼

傳一張最近看的小冊的老哥畫的圖,賊穩

instanceof

類似于typeof判斷數據類型,因為起內部機制是通過原型鏈來判斷的所以要更加嚴謹,但是對于原始類型想直接通過instanceof來判斷是不行的,但是我們還是有辦法讓它判斷原始類型的代碼如下:

class   PrimitiveString{static [symbol.hasInstance(x){return typeof x=='string'}]
}
console.log('hello' instanceof PrimitiveString) //true
復制代碼

typeof()

typeof()對于原始數據類型:number,string,boolean,symbol(es6引入的新的數據類型表示第一無二的值)除了null都可以顯示正確類型,除了null,對于對象來說除了function都會返回object,所以此方法并不能正確返回數據類型

every()

用于檢測數組中的所有元素是否都符合指定條件 every() 方法使用指定函數檢測數組中的所有元素: 如果數組中檢測到有一個元素不滿足,則整個表達式返回 false ,且剩余的元素不會再進行檢測。 如果所有元素都滿足條件,則返回 true。 注意: every() 不會對空數組進行檢測。 注意: every() 不會改變原始數組。 example1:數組中的元素是否滿足大于等于4

let arr=[12,4,56,78,90]
let boolean=arr.every(item=>item>=4)//true
復制代碼

map

map() 方法返回一個由原數組中的每個元素調用一個指定方法后的返回值組成的新數組。 傳遞給map()的函數的調用方式和傳遞給forEach()的函數的調用方式一樣。但傳遞給map()的函數應該有返回值。注意:map()返回的是新數組:它不修改調用 的數組。

function square(arr){return arr.map(function(item){return item*item})
}
let arr=[1,2,3,4,5,6]
let arr2=square(arr)
console.log(arr2) //[1, 4, 9, 16, 25, 36]
復制代碼

includes

與ES5中的indexOf類似,indexOf用來查找某個元素在數組中的位置有則返回元素位置索引,沒有則返回-1,但是不能判斷是否有NaN的元素;ES6中提供了Array.inclides()此方法只返回true和false即包含不包含,不能定位元素可判斷NaN,可兩個結合使用。 Array.inclides()的第二個參數表示判斷的起始位置,若為負數表示從右起第幾個但是不改變判斷方向。

filter:

用于把Array的某些元素過濾掉返回剩下的元素,參數接受一個函數,函數作用于每一個元素,根據返回值是true或false決定保留還是丟棄該元素。filter是一個高階函數關鍵在于正確實現一個篩選函數。 filter()接收的回調函數有三個,第一個是表示某個元素,第二個表示位置,第三個表示數組本身

example1:數組去重

letr,arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
r = arr.filter(function (element, index, self) {return self.indexOf(element) === index;
});
復制代碼

去除重復元素依靠的是indexOf總是返回第一個元素的位置,后續的重復元素位置與indexOf返回的位置不相等,因此被filter濾掉了。

example2:a數組中刪除b數組中的元素

let a=[1,2,3,4,5,6],b=[1,2,3];
let c=a.filter(item=>!b.includes(item))
console.log(c) //[4,5,6]
復制代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388702.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388702.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388702.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

構建圖像金字塔_我們如何通過轉移學習構建易于使用的圖像分割工具

構建圖像金字塔Authors: Jenny Huang, Ian Hunt-Isaak, William Palmer作者: 黃珍妮 , 伊恩亨特伊薩克 , 威廉帕爾默 GitHub RepoGitHub回購 介紹 (Introduction) Training an image segmentation model on new images can be daunting, es…

PHP mongodb運用,MongoDB在PHP下的應用學習筆記

1、連接mongodb默認端口是:27017,因此我們連接mongodb:$mongodb new Mongo(localhost) 或者指定IP與端口 $mongodb new Mongo(192.168.127.1:27017) 端口可改變若mongodb開啟認證,即--auth,則連接為: $mongodb new …

a標簽

a標簽定義超鏈接&#xff0c;用于從一張頁面鏈接到另一張頁面&#xff0c;它最重要的屬性是 href 屬性&#xff0c;它指示鏈接的目標。 <a href"http://www.w3school.com.cn">W3School</a> 最常用的就像這樣添加一個鏈接&#xff0c;如果是點擊事件的話&…

MFC程序執行過程剖析

一 MFC程序執行過程剖析 1&#xff09;我們知道在WIN32API程序當中&#xff0c;程序的入口為WinMain函數&#xff0c;在這個函數當中我們完成注冊窗口類&#xff0c;創建窗口&#xff0c;進入消息循環&#xff0c;最后由操作系統根據發送到程序窗口的消息調用程序的窗口函數。而…

CF888E Maximum Subsequence(meet in the middle)

給一個數列和m&#xff0c;在數列任選若干個數&#xff0c;使得他們的和對m取模后最大&#xff08; \(1<n<35\) , \(1<m<10^{9}\)&#xff09; 考慮把數列分成兩份&#xff0c;兩邊分別暴力求出所有的可能&#xff0c;那么對于一個數列中每一個數字\(x\)&#xff0…

virtualbox php mac,詳解mac下通過docker搭建LEMP環境

在mac下通過docker搭建LEMP環境境1.安裝virtualbox。由于docker是在lxc環境的容器2.安裝boot2docker&#xff0c;用于與docker客戶端通訊> brew update> brew install docker> brew install boot2docker3.初始化boot2docker&#xff0c;也就是在virtualbox上安裝一個d…

SpringBoot項目打war包部署Tomcat教程

一、簡介 正常來說SpringBoot項目就直接用jar包來啟動&#xff0c;使用它內部的tomcat實現微服務&#xff0c;但有些時候可能有部署到外部tomcat的需求&#xff0c;本教程就講解一下如何操作 二、修改pom.xml 將要部署的module的pom.xml文件<packaging>節點設置為war <…

在VS2005中使用添加變量向導十分的

在VS2005中使用添加變量向導十分的方便&#xff0c;但是如何手動添加呢。可以分為2步&#xff1a; 1. 在控件對應的類的頭文件中添加相應的變量聲明&#xff08;如&#xff1a;CString m_strResult&#xff09; 2. 在類的實現文件中的DoDataExchange(CDataExchange* pDX)函數…

關于如何使用xposed來hook微信軟件

安卓端 難點有兩個 收款碼的生成和到帳監聽需要源碼加 2442982910轉載于:https://www.cnblogs.com/ganchuanpu/p/10220705.html

GitHub動作簡介

GitHub Actions can be a little confusing if you’re new to DevOps and the CI/CD world, so in this article, we’re going to explore some features and see what we can do using the tool.如果您是DevOps和CI / CD領域的新手&#xff0c;那么GitHub Actions可能會使您…

java returnaddress,JVM之數據類型

《Java虛擬機規范》閱讀筆記-數據類型1.概述Java虛擬機的數據類型可分為兩大類&#xff1a;原始類型(Primitive Types&#xff0c;也稱為基本類型)和引用類型(Reference Types)。Java虛擬機用不同的字節碼指令來操作不同的數據類型[1] 。2.原始類型原始類型是最基本的元素&…

C# matlab

編譯環境&#xff1a;Microsoft Visual Studio 2008版本 9.0.21022.8 RTMMicrosoft .NET Framework版本 3.5已安裝的版本: ProfessionalMicrosoft Visual Basic 2008 91986-031-5000002-60050Microsoft Visual Basic 2008Microsoft Visual C# 2008 91986-031-5000002-60050…

洛谷P3273 [SCOI2011] 棘手的操作 [左偏樹]

題目傳送門 棘手的操作 題目描述 有N個節點&#xff0c;標號從1到N&#xff0c;這N個節點一開始相互不連通。第i個節點的初始權值為a[i]&#xff0c;接下來有如下一些操作&#xff1a; U x y: 加一條邊&#xff0c;連接第x個節點和第y個節點A1 x v: 將第x個節點的權值增加vA2 x…

基于容器制作鏡像

一。鏡像基礎 一。基于容器制作鏡像 1. 查看并關聯運行的容器 [ghlocalhost ~]$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4da438fc9a8e busybox …

照顧好自己才能照顧好別人_您必須照顧的5個基本數據

照顧好自己才能照顧好別人I am pretty sure that on your data journey you came across some courses, videos, articles, maybe use cases where someone takes some data, builds a classification/regression model, shows you great results, you learn how that model wo…

matlab數字仿真實驗,DVR+備用電源自動投入的MATLAB數字仿真實驗仿真實驗

一、動態電壓恢復器(DVR)的數字仿真實驗動態電壓恢復器(Dynamic Voltage Restorer&#xff0c;DVR)是一種基于電力電子技術的串聯補償裝置&#xff0c;通常安裝在電源與敏感負荷之間&#xff0c;其作用在于&#xff1a;保證電網供電質量&#xff0c;補償供電電網產生的電壓跌落…

c#,xp系統,Matlab6.5

編譯環境&#xff1a;c#&#xff0c;xp系統&#xff0c;Matlab6.5 新建一個窗體項目&#xff0c;添加matlab引用。 然后試了四種方式調用matlab&#xff1a; 第一種 view plaincopy to clipboardprint?MLApp.MLAppClass matlab new MLApp.MLAppClass(); matlab.Visible 1;…

java script 對象

java script 對象 1.創建方式 1&#xff09;通過字面量的形式創建 例&#xff1b;var stt{x:1,y:2,y:3}; 或&#xff1b;var stt{ x:1, y:2, for:3 } 注意關鍵字必須放到引號中間 2&#xff09;通過new創建對象 例&#xff1a;var new stt(); stt.name 小魚; stt.age 20…

認識數據分析_認識您的最佳探索數據分析新朋友

認識數據分析Visualization often plays a minimal role in the data science and model-building process, yet Tukey, the creator of Exploratory Data Analysis, specifically advocated for the heavy use of visualization to address the limitations of numerical indi…

架構探險筆記10-框架優化之文件上傳

確定文件上傳使用場景 通常情況下&#xff0c;我們可以通過一個form&#xff08;表單&#xff09;來上傳文件&#xff0c;就以下面的“創建客戶”為例來說明&#xff08;對應的文件名是customer_create.jsp&#xff09;&#xff0c;需要提供一個form&#xff0c;并將其enctype屬…