javascript basic concept 2023-05-10

1. javascript運行環境 Node.js

Node.js or Node is an open-source, cross-platform, JavaScript runtime environment(JSRE) that executes JavaScript code outside of a web browser. Node.js基于 Chrome V8 引擎

Node.js只是javascript runtime之一,瀏覽器也是javascript runtime

Q&A

  • javascript是單線程的,為什么可以執行異步操作?
    如以下異步代碼,console.log("Asynchronous")需要10秒后才執行,但它不會block console.log(greet_two);
    setTimeout is asynchronous so it runs in background, allowing code after it to execute while it runs
let greet_one = "Hello"
let greet_two = "World!!!"
console.log(greet_one)
setTimeout(function(){
    console.log("Asynchronous");
}, 10000)
console.log(greet_two);

因為runtime維護了線程池,所有的異步操作都交給了runtime執行

之所以說JavaScript是單線程,是因為瀏覽器在運行時只開啟了一個JS引擎線程來解析和執行JS。為什么只有一個引擎呢?如果同時有兩個線程去操作DOM,涉及線程安全問題,導致渲染頁面的復雜度增加

雖然JavaScript是單線程的,可是瀏覽器內部不是單線程的。一些I/O操作、定時器的計時和事件監聽(click, keydown...)等都是由瀏覽器提供的其他線程來完成的

2. 運行環境管理 using nvm

像go/python一樣,Node.js也有很多版本,我們可以通過nvm選擇特定版本的Node.js作為運行環境

nvm: Node Version Manager.
install nvm: https://github.com/nvm-sh/nvm
nvm usage:

nvm install 16.19.1
$ nvm use 16
Now using node v16.9.1 (npm v7.21.1)
$ node -v
v16.9.1

3. javascript包管理 using NPM

NPM is a package manager for Node.js packages, which will allow you to install third party libraries (other people's code) by using the command line.

www.npmjs.com hosts thousands of free packages to download and use. The NPM program is installed on your computer when you install Node.js.

usage:

npm install <foo>  # add the <foo> dependency to your project

4. 語法

變量/常量定義

變量定義使用let
常量定義使用const

> let b = 1
undefined
> b = 2
2
> 
> const a = 1
undefined
> a = 2
Uncaught TypeError: Assignment to constant variable.
> 
> const obj = {a:1}
undefined
> obj.a = 2 // 正常賦值。因為obj是一個引用,記錄的是內存地址,引用本身并沒有發生變化
2
> 

如果你需要一個不變的值,并且確定它的值在聲明后不會更改,那么使用 const 可以幫助減少代碼中錯誤賦值的可能性。
如果需要可變的量,那么使用 let 即可

注意:對于引用類型的變量,=====只會判斷引用的地址是否相同,而不會判斷對象具體里屬性以及值是否相同

支持embedding方式創建object

js支持通過embedding創建object,類似golang中使用struct-embedding創建新struct一樣(https://gobyexample.com/struct-embedding)

如果你不需要給object的屬性再起名字,可以直接通過embedding創建object

> let name = "john"
undefined
> let age = 10
undefined
> let doHomeWork = () => { return "doing homework" }
undefined
> let student1 = {name, age, doHomeWork} // create obj by embedding other objs
undefined
> student1
{ name: 'john', age: 10, doHomeWork: [Function: doHomeWork] }
> 

js is Prototype-based

js is a Prototype-based language. Prototype-based programming is a style of object-oriented programming in which classes are not explicitly defined, but rather derived by adding properties and methods to an instance of another class or, less frequently, adding them to an empty object.

In simple words: this type of style allows the creation of an object without first defining its class.

// Example of true prototypal inheritance style 
// in JavaScript.

// object creation using the literal 
// object notation {}.
const foo = { name: "foo", one: 1, two: 2 };

// Another object.
const bar = { two: "two", three: 3 };

// Object.setPrototypeOf() is a method introduced in ECMAScript 2015.
// For the sake of simplicity, let us pretend 
// that the following line works regardless of the 
// engine used:
Object.setPrototypeOf(bar, foo); // foo is now the prototype of bar.

// If we try to access foo's properties from bar 
// from now on, we'll succeed. 
bar.one; // Resolves to 1.

// The child object's properties are also accessible.
bar.three; // Resolves to 3.

// Own properties shadow prototype properties
bar.two; // Resolves to "two"
bar.name; // unaffected, resolves to "foo"
foo.name; // Resolves to "foo"

For another example:

const foo = { one: 1, two: 2 };

// bar.[[prototype]] = foo
const bar = Object.create(foo);

bar.three = 3;

bar; // { three: 3 }
bar.one; // 1
bar.two; // 2
bar.three; // 3

原型

JavaScript 中所有的對象都有一個內置屬性,稱為它的 prototype(原型)。它本身是一個對象,故原型對象也會有它自己的原型,逐漸構成了原型鏈。原型鏈終止于擁有 null 作為其原型的對象上。

有個對象叫 Object.prototype,它是最基礎的原型,所有對象默認都擁有它。Object.prototype 的原型是 null,所以它位于原型鏈的終點

設置原型

使用 Object.create
const personPrototype = {
  greet() {
    console.log("hello!");
  },
};

const carl = Object.create(personPrototype); // create改叫createFrom更貼切
carl.greet(); // hello!
使用構造函數

如果我們設置一個構造函數的 prototype,我們可以確保所有用該構造函數創建的對象都被賦予該原型:

const personPrototype = {
  greet() {
    console.log(`你好,我的名字是 ${this.name}!`); // `this`就是調用方
  },
};

// 構造函數Person
function Person(name) {
  this.name = name;
  this.sing = function() {
    console.log(`${this.name} singing!`); // `this`就是調用方
  }
}

Object.assign(Person.prototype, personPrototype);
const carl = new Person('carl');
carl.greet();  // 你好,我的名字是 carl!
// new 在執行時會做四件事情:

// ??① 在內存中創建一個新的空對象。

// ??② 讓 this 指向這個新的對象。

// ??③ 執行構造函數里面的代碼,給這個新對象添加屬性和方法。

// ??④ 返回這個新對象(所以構造函數里面不需要 return )


const bob = new Person('bob');
console.log(bob.greet === carl.greet); //  True. 因為都是引用prototype.greet -> 構造函數通過原型分配的函數是所有對象所共享的
console.log(bob.sing === carl.sing); //  false. 自有的sing各自持有而不是引用同一份method,其實挺浪費內存空間的

Named Export and Default Export

Default Export (export default)

You can have one default export per file. When you import you have to specify a name and import like so:

import MyDefaultExport from "./MyFileWithADefaultExport";

You can give this any name you like.

Named Export (export)

With named exports, you can have multiple named exports per file. Then import the specific exports you want surrounded in braces:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

Or it's possible to use a default along with named imports in the same statement:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

js語言特性

數據類型體系

  • 基本數據類型。基本數據類型對象直接分配在棧中,如數字、字符串,然后持有引用

    JavaScript 中的基本數據類型(例如字符串、數字、布爾值等)是不可變的。這意味著當你重新為一個變量賦值時,實際上是在內存中創建了一個新的值,并將變量引用這個新值。原始值在內存中的位置不會改變,但變量引用的內存地址將指向新值。

    let s = 'hello'
    s = 'world'
    

    在這個例子中,我們首先將變量 s 賦值為字符串 'hello'。當我們將 s 重新賦值為 'world' 時,實際上是創建了一個新的字符串 'world',并將變量 s 指向這個新字符串。原始字符串 'hello' 仍然存在于內存中,但變量 s 現在引用的是新字符串 'world' 的內存地址。

  • 容器類型。容器類型的對象分配在堆中,然后在棧中持有堆對象的引用

動態語言,變量xxx的類型可以隨便改,如xxx = 1然后xxx = [1,2,3],這個特性決定了動態語言都要依賴引用(實際上是對指針的再封裝)。如果像golang把xxx固定為一個int長度的內存空間,那xxx就無法再被賦值為數組了。對任何數據類型重新賦值,都是修改了引用;而對引用的容器類型對象進行局部修改,不改變引用本身,整體和Python的類型機制相同。可見動態語言出于其動態特性,類型系統都是一個套路

因此,js的const,it does not define a constant value. It defines a constant reference to a value instance.

值傳遞

在 JavaScript 中,所有參數都是按值傳遞的。但是對于對象(包括數組和函數),傳遞的值本身是對象的引用,引用作為值,因此它們的行為看起來像是按引用傳遞。這樣的話,如果你在函數內部修改了一個對象參數的屬性,那么在函數外部,這個屬性的原始對象也會被修改。

JavaScript 有 5 種基本的數據類型,分別是:bool、null、undefined、string 和 number,還有另外三種引用類型: Array、Function 和 Object。此外,在 ES6 中,引入了一種新的數據類型 - Symbol - 是一種原始數據類型,像數字或字符串一樣按值進行傳遞。

總結一下,基本類型(Number、String、Boolean、Undefined、Null、Symbol)由于空間小、數據簡單,Javascript按值傳遞(復制一份到新的棧),引用類型(Object)由于空間大、數據復雜,Javascript按共享傳遞(復制引用到新的棧)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內容