JavaScript
介紹
- JavaScript是基于原型,面向?qū)ο?弱類型的動(dòng)態(tài)腳本語(yǔ)言,它從函數(shù)式語(yǔ)言中借鑒了一些強(qiáng)大的特性,如閉包和高階函數(shù)
- js是根據(jù)ECMAScript語(yǔ)言標(biāo)準(zhǔn)來(lái)實(shí)現(xiàn)的
node使用了 v8 的原因,它的實(shí)現(xiàn)很接近標(biāo)準(zhǔn),此外它還提供了一些標(biāo)準(zhǔn)之外使用的附加功能,
- js基礎(chǔ),語(yǔ)言基礎(chǔ)適用 node 瀏覽器 語(yǔ)言標(biāo)準(zhǔn)
- v8 中得js 其特性是部分是瀏覽器不支持的 還提供了一些非特性的東西,能夠解決一些常見(jiàn)的需求
類型
- js的類型和可以簡(jiǎn)單的分為兩種,基本類型和復(fù)雜類型
- 基本類型包括,number,boolean,string,null 和 undefined
- 復(fù)雜類型包括 array ,function 和object
- 例子:
書(shū)中用的還是var 但是var來(lái)聲明變量會(huì)有一些不可知問(wèn)題
- 所以新版本里面全部用let 和const 來(lái)聲明變量
- let 代表的是可變變量
- const 代表的是不可變變量
//基本類型
let a = 5;
let b = a;
b = 6;
console.log(a);
console.log(b);
console.log('``````````````````````````````````````');
//復(fù)雜類型
let x = ['hello', 'world'];
let y = x;
console.log(y[0]);
y[0] = 'bye';
console.log(x[0]);
console.log(y[0]);
- 上述例子中得第二部分,b和a包含了對(duì)值的相同引用,因此,當(dāng)通過(guò)b修改數(shù)組的第一個(gè)元素的時(shí)候,a相應(yīng)的值也變了,說(shuō)明a[0]=== b0
類型的困惑
- 在js中準(zhǔn)確無(wú)誤判斷變量值的類型并非易事
- 相對(duì)于大部分基本類型來(lái)說(shuō) js于其他面向?qū)ο蟮恼Z(yǔ)言一樣都有構(gòu)造器,
- 例子
let a = 'woot';
let b = new String('woot');
console.log(typeof a);
console.log(typeof b);
//檢查這個(gè)值的詩(shī)句類型是否屬于 string
console.log(a instanceof String);
console.log(b instanceof String);
//判斷變量值是否相等
console.log(a == b);
//判斷地址值是否相等
console.log(a === b);
- 以上例子可以表明 直接創(chuàng)建的和new出來(lái)的在內(nèi)存中會(huì)實(shí)例化兩個(gè)不同的地址出來(lái),即使內(nèi)容相同,地址值不同
- 需要了解一些特定情況下的判斷 false: null , undefined, ' ',還有0
let a = 0;
if (a) {
//這里永遠(yuǎn)執(zhí)行不到
}
a==false //true
a=== false // false
還有值得注意的是 類型檢測(cè) typeof 不會(huì)把 null 識(shí)別為null 也不會(huì)吧[]識(shí)別為array
- image.png
但是這里v8給我們提供了判斷是否是數(shù)組類型的方式
在瀏覽器中我們通常要查看對(duì)象內(nèi)部的[[Class]]值:
Object.prototype.toString.call([]) == '[object Array]'
,該值是不可變得,有利我們?cè)诓煌纳舷挛闹袑?duì)數(shù)組類型進(jìn)行判定,而instanceof Array
只適用于在與數(shù)組初始化在相同上下文才有效,也就是初始化在相同環(huán)境內(nèi)才有效
函數(shù)
- 在js中,函數(shù)最為==重要==
- 例子 他們都屬于一等函數(shù):可以作為引用儲(chǔ)存在變量中,隨后可以像其他對(duì)象一樣,進(jìn)行傳遞
let a = function () { };
console.log(a);//將函數(shù)作為參數(shù)傳遞的
- js中所有的函數(shù)都已命名,有一點(diǎn)很重要,就是要能區(qū)分出函數(shù)名和變量名
let a = function () { };
console.log(a);//將函數(shù)作為參數(shù)傳遞的
let b = function b() {
if ('function' == typeof b) {//書(shū)中數(shù)這個(gè)結(jié)果是 true 但是我沒(méi)有打印出任何結(jié)果
console.log('true');
}else{
console.log('false');
}
};
b(); //原來(lái)是我沒(méi)有調(diào)用..
- 下屬代碼函數(shù)被調(diào)用,
this
的值是全局對(duì)象,在瀏覽器中,就是window對(duì)象
function c(){
if (window ==this){
console.log("true");
} else{
console.log("false");
}
}
c();//這樣調(diào)用會(huì)報(bào)錯(cuò) window is not defined
- 調(diào)用下列函數(shù)的時(shí)候,使用.call和.apply方法可以改變this的值
function a (b,c){
b == 'first';//true
c == 'second';//ture
}
a.call({a:'b'},'first','second');
a.apply({a:'b'},['first','seccond']);
- call 和 apply 的區(qū)別在于 ,call接收參數(shù)列表,而 apply 只接受一個(gè)參數(shù)數(shù)組
函數(shù)的參數(shù)數(shù)量
- 函數(shù)的參數(shù)數(shù)量 也就是函數(shù)聲明的時(shí)候可以接收的參數(shù)數(shù)量,和表示數(shù)組內(nèi)有多少個(gè)值是一樣的 用的是 length來(lái)表示
閉包
- 在js 中,每次函數(shù)調(diào)用的時(shí)候,新的作用域就會(huì)產(chǎn)生.
- 在某個(gè)作用域中得定一個(gè)的變量只能在該作用域或其內(nèi)部作用域中才能訪問(wèn)到
//這里用var和用let 的結(jié)果會(huì)不一樣,var 的作用域更大 且支持重復(fù)命名
//let是不支持重復(fù)命名的
var a = 5;
function woot() {
a ===5 ;//true
var a = 6;
function test() {
a === 6; //true
}
test();
};
woot();
- 自執(zhí)行函數(shù)是一種機(jī)制,通過(guò)這種機(jī)制聲明和調(diào)用一個(gè)匿名函數(shù),能夠達(dá)到僅定義一個(gè)新的作用域的作用
let a = 3;
(function () {
let a = 5;
})();
a ==3;//true
- 自執(zhí)行函數(shù)對(duì)聲明私有變量是很有用的,可以讓私有變量不被其他代碼訪問(wèn)
類
- js中是沒(méi)有
class
關(guān)鍵字的,類只能通過(guò)函數(shù)來(lái)定義
function Animal ( ) {}
- 要給所有Animal的實(shí)例定義函數(shù),可以通過(guò) prototype(屬性使您有能力向?qū)ο筇砑訉傩院头椒?
Animal.prototype.eat = function (food) {
//eat method
}
- 這里在prototype的函數(shù)內(nèi)部,this 并非指向 global 對(duì)象
- 而是指向這個(gè)函數(shù)對(duì)象
function Animal (name) {
this.name = name;
}
Animal.prototype.getName(){
return this.name;//這里有問(wèn)題 我用的idea
}
let animal = new Animal('tobi');
a.getName() == 'tobi'; //true
繼承
js有基于原型的繼承特點(diǎn)
定一個(gè)一個(gè)來(lái)自Animal 的構(gòu)造器
定義繼承,首先創(chuàng)造一個(gè)animal的對(duì)象,將其賦值給Ferret.prototype
可以為子類定義屬性和方法
可以通過(guò)prototype重寫(xiě)和調(diào)用父類函數(shù)
不會(huì)破會(huì)instanceof的結(jié)果
- image.png
這里我們主要看后面的 V8的解決辦法
try{} catch{}
異常捕捉
當(dāng)函數(shù)拋出錯(cuò)誤時(shí),代碼就會(huì)停止
我們這個(gè)通過(guò)這個(gè)方法,讓代碼繼續(xù)進(jìn)行下去
- image.png