国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《你不知道的JS上》筆記

VPointer / 1958人閱讀

摘要:隱式綁定即綁定到最頂層或最近調用對象上顯式綁定即用或手動進行綁定方法實現綁定構造函數不存在其實在中不存在構造函數,我們所說的構造函數其實就是普通的函數,它只是用被構造調用而已。

JS是編譯型語言

編譯發生在代碼執行前幾微秒,簡單來說就是js在執行前要進行編譯,編譯過程發生在代碼執行前幾微妙,甚至更短。

編譯的步驟

詞法分析
以var a = 2 為例,詞法分析會將其分成三個有意義的代碼塊即詞法單元。

語法分析
將詞法單元組合生成代表了程序語法的結構的樹,即抽象語法書(AST)。

代碼生成
將AST生成可執行的代碼。即將AST轉化成一組機器指令。???

LHS RHS

如果查找的目的是對變量進行賦值,那么就會使用 LHS 查詢;如果目的是獲取變量的值,就會使用 RHS 查詢。

詞法作用域

決定于你在寫代碼時的塊級作用域

優化

依賴于詞法的靜態分析

eval with 會創建新的作用域

在詞法分析階段,無法知道eval with會對作用域做怎樣的修改,此時引擎不再對作用域進行任何優化

函數作用域 函數聲明 函數表達式

區分函數聲明和表達式最簡單的方法是看 function 關鍵字出現在聲明中的位
置(不僅僅是一行代碼,而是整個聲明中的位置)。如果 function 是聲明中
的第一個詞,那么就是一個函數聲明,否則就是一個函數表達式。

let

隱式的生成塊級作用域

不存在變量提升

提升 原因

變量(包括函數在內)的所有聲明都會優先執行,只有聲明本身會提升,而賦值或其他運行邏輯會留在原位置

過程

這意味著無論作用域中的聲明出現在什么地方,都將在代碼本身被執行前首先進行處理。
可以將這個過程形象地想象成所有的聲明(變量和函數)都會被“移動”到各自作用域的
最頂端,這個過程被稱為提升。
聲明本身會被提升,而包括函數表達式的賦值在內的賦值操作并不會提升。

閉包 定義

當函數能夠記住或訪問所在的詞法作用域,及時是被作用域外調用,就產生了閉包

模塊

現代模塊機制

未來的模塊機制

關于this 綁定時間點

是在函數運行時綁定的,而非定義時。它的上下文取決于函數調用時的各種條件,和在哪里定義的沒有關系,只取決于函數的調用方式。

綁定過程

當函數被調用時,會創建一個執行上下文,在這個上下文里包含了函數在哪里沒調用(調用棧),調用函數的方法,參數等。this作為執行上下文的一個屬性,可以在函數執行的過程中用到。

綁定類型

默認綁定
即綁定到全局,嚴格模式下回綁定到undefined。

function foo() {
  console.log( this.a );
}
var a = 2;
(function(){
  "use strict";
   foo(); // 2
})()

隱式綁定
即綁定到最頂層(或最近調用對象)上

function fun() {
  console.log(this.a)
}
var obj2 = {
  a: 3,
 fun: fun,
}
var obj1 = {
  a: 2,
  obj2: obj2,
}
obj1.obj2.fun() // 3

顯式綁定
即用call或apply手動進行綁定

bind方法實現

new綁定(構造函數)

不存在
其實在js中不存在構造函數,我們所說的構造函數其實就是普通的函數,它只是用new被“構造調用”而已。

new發生了什么?

創建(或者說構造)一個全新的對象。

這個新對象會被執行[[原型]]連接。

這個新對象會綁定到函數調用的this。

如果函數沒有返回其他對象,那么new表達式中的函數調用會自動返回這個新對象。

箭頭函數 =>

對象 內置對象

基本類型在需要的時候(比如說獲取長度),會被引擎默認轉成內置對象,從而進行方法的調用。
基礎類型并不是繼承自內置對象?

    var strPrimitive = "I am a string";
    typeof strPrimitive; // "string"
    strPrimitive instanceof String; // false
    var strObject = new String( "I am a string" );
    typeof strObject; // "object"
    strObject instanceof String; // true
    Object.prototype.toString.call( strObject ); // [object String] 
null
typeof null === Object; 

原理是這樣的,不同的對象在底層都表示為二進制,在 JavaScript 中二進制前三位都為 0 的話會被判
斷為 object 類型,null 的二進制表示是全 0,自然前三位也是 0,所以執行 typeof 時會返回“object”

拷貝

淺拷貝
Object.assign({}, obj)

深拷貝
JSON.stringify

屬性描述符
getOwnPropertyDescriptor(myObj, "a")
defineProperty
Object.defineProperty(myObj, "a", {
  value: 2,            
  ?writable: true,
  configurable: true, 
  enumerable: true 
?})
Getter 、Setter
var obj = {
  get a() {
    return this._a_
  },
  set a(val) {
   this._a_ = val * 5
  }
}
obj.a = 10
console.log(obj.a) // 50
?
var obj2 = {}
Object.defineProperty(obj2, "a", {
  get: function() {
    return this._a_
  },
  set: function(val) {
    this._a_ = val * 2
  }
})
obj2.a = 15
console.log(obj2.a) // 30
存在性

in
"a" in obj1 會檢查obj及其原型鏈上是否有"a"

hasOwnProperty
不會檢查原型鏈,如果需要可以Object.prototype.hasOwnProperty.call(myObj, "a")

原型(prototype) constructor

返回實例對象O的構造函數(的引用)。任何一個prototype對象都有一個constructor屬性,指向它的構造函數,每一個實例也有一個constructor屬性,默認調用prototype對象的constructor屬性?
例如

function Test() {
  this.name = "test"
}
var test = new Test()
console.log(test.constructor === Test) // true
類constructor

構造函數 constructor 是用于創建和初始化類中創建的一個對象的一種特殊方法.

class Polygon {
    constructor() {
        this.name = "Polygon";
    }
}
class Square extends Polygon {
    constructor() {
        super();
    }
}
class Rectangle {}
Object.setPrototypeOf(Square.prototype, Rectangle.prototype);
console.log(Object.getPrototypeOf(Square.prototype) === Polygon.prototype); //false
console.log(Object.getPrototypeOf(Square.prototype) === Rectangle.prototype); //true
let newInstance = new Square();
console.log(newInstance.name); //Polygon?
proto

實例對象__proto__指向生成改對象的構造函數的原型
例如

|function Test() {
  this.name = "test"
}
Test.prototype = {
  color: "red"
}
var test = new Test()
console.log(test.__proto__ === Test.prototype) // true
console.log(test.__proto__)
Object.create
var foo = {
something: function() {
  console.log( "Tell me something good..." );
}
};
var bar = Object.create( foo ); 
bar.something(); // Tell me something good...
Object.create(..) 會創建一個新對象(bar)并把它關聯到我們指定的對象(foo)

這樣 我們就可以充分發揮 [[Prototype]]
機制的威力(委托)并且避免不必要的麻煩
(比如使 用 new 的構造函數調用會生成 .prototype 和 .constructor 引用)。
?

繼承 原型繼承

缺點
實例的屬性都會指向同一個引用
實現

function Parent() {
  this.names = [1, 2, 3]
}
function Child() {
  
}
Child.prototype = new Parent()
var child1 = new Child()
var child2 = new Child()
child1.names.push(4)
console.log(child1.names) // [1,2, 3,4]
console.log(child2.names) // [1,2, 3,4]
借用構造函數

實現

function Parent() {
  this.names = [1, 2, 3]
  this.getName = function () {
    console.log(this.name)
  }
}
function Child() {
  Parent.call(this)
}
var child1 = new Child()
var child2 = new Child()
child1.names.push(4)
console.log(child1.names)
console.log(child2.names)

缺點
每個子實例都會實例化方法一次,內存爆炸

組合繼承(最常用)

實現

function Parent() {
  this.names = [1, 2, 3]
}
Parent.prototype.getName = function () {
  console.log(this.names)
}
function Child() {
  Parent.call(this)
}
Child.prototype = new Parent()
var child1 = new Child()
var child2 = new Child()
child1.names.push(4)
child1.getName()
child2.getName()

缺點

子類實例上有一份父類的屬性,二者重復造成內存浪費

父類的構造函數被調用了兩次?

寄生式組合繼承

實現

function Parent() {
  this.names = [1, 2, 3]
}
Parent.prototype.getName = function () {
  console.log(this.names)
}
function Child() {
  Parent.call(this)
}
Child.prototype = Object.create(Parent.prototype)
var child1 = new Child()
var child2 = new Child()
child1.names.push(4)
child1.getName()
child2.getName()

優點
屬性不會再原型鏈上重復

行為委托

js中的繼承其實就是在對象間建立關聯關系,而行為委托就是建立這種關聯關系的紐帶。

("原型")面向對象風格
function Foo(who) {
  this.me = who;
}
Foo.prototype.identify = function () {
  return "I am" + this.me;
};
function Bar(who) {
  Foo.call(this,who);
}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.speak = function () {
  alert("Hello," + this.identify() + ".");
};
var b1 = new Bar("b1");
var b2 = new Bar("b2");
b1.speak();
b2.speak();
對象關聯風格
Foo = {
  init:function (who) {
    this.me = who;
  },
  identify:function () {
    return "I am" + this.name
  }
};
Bar = Object.create(Foo);
Bar.speak = function () {
  alert("hello," + this.identify() + ".");
};
var b3 = Object.create(Bar);
b3.init("b3");
var b4 = Object.create(Bar);
b4.init("b4");
b1.speak();
b2.speak();

?

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97508.html

相關文章

  • 你不知道JS》讀書筆記---作用域及閉包

    摘要:注此讀書筆記只記錄本人原先不太理解的內容經過閱讀你不知道的后的理解。作用域及閉包基礎,代碼運行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內容經過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎,JS代碼運行的幕后工作者:引擎及編譯器。引擎負責JS程序的編譯及執行,編譯器負責詞法分析和代碼生成。那么作用域就像一個容器,引擎及編譯器都從這里提取東西。 ...

    denson 評論0 收藏0
  • 筆記你不知道JS讀書筆記——異步

    摘要:異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件循環隊列中。 基礎:瀏覽器 -- 多進程,每個tab頁獨立一個瀏覽器渲染進程(瀏覽器內核) 每個瀏覽器渲染進程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎) JS引擎線程負...

    junnplus 評論0 收藏0
  • 筆記-你不知道JS-原型

    摘要:如果存在于原型鏈上層,賦值語句的行為就會有些不同。中包含的屬性會屏蔽原型鏈上層的所有屬性,因為總是會選擇原型鏈中最底層的屬性。如果不直接存在于中而是存在于原型鏈上層時會出現的三種情況。類構造函數原型函數,兩個函數通過屬性和屬性相關聯。 1 [[Prototype]] 對于默認的 [[Get]] 操作來說,如果無法在對象本身找到需要的屬性,就會繼續訪問對象的 [[Prototype]] ...

    vincent_xyb 評論0 收藏0
  • 筆記-你不知道JS-原型

    摘要:如果存在于原型鏈上層,賦值語句的行為就會有些不同。中包含的屬性會屏蔽原型鏈上層的所有屬性,因為總是會選擇原型鏈中最底層的屬性。如果不直接存在于中而是存在于原型鏈上層時會出現的三種情況。類構造函數原型函數,兩個函數通過屬性和屬性相關聯。 1 [[Prototype]] 對于默認的 [[Get]] 操作來說,如果無法在對象本身找到需要的屬性,就會繼續訪問對象的 [[Prototype]] ...

    AndroidTraveler 評論0 收藏0
  • 你不知道JS》讀書筆記之閉包在循環中應用

    摘要:閉包在循環中的應用延遲函數的回調會在循環結束時才執行事實上,當定時器運行時即使沒給迭代中執行的是多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個出來。 閉包在循環中的應用 延遲函數的回調會在循環結束時才執行;事實上,當定時器運行時即使沒給迭代中執行的是 setTime(..., 0),多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個6出來。 for(var...

    weapon 評論0 收藏0
  • 筆記-你不知道JS-閉包

    showImg(https://segmentfault.com/img/bVbtd6M?w=1181&h=1365); showImg(https://segmentfault.com/img/bVbtd6T?w=1243&h=1984);

    Jiavan 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<