六大類型
Undefined
Null
Bollean
String
Number
Object
對象類型
原生對象:
- 構造函數(shù):Boolean, String, Number, Object, Function, Array, Date, RegExp, Error
- 對象: Math, JSON
宿主對象: window, navigator, document
瀏覽器擴展對象: - ActiveXObject, XML, Debug, Script, VBArray
- 逐漸被棄用
隱式類型轉換:
- Undefined轉為Number為NAN
- 空字符串轉為Boolean為false
- 所有的對象轉為Boolean都是true
類型識別:
- typeof:
- 判斷基礎類型,返回的是字符串
- 如果是對象則返回'object'。
- typeof null === 'object'
- typeof Function === 'function'
- instanceof
- 判斷對象類型,可判斷子類
- 不能判別原始類型:1 instanceof Number === false
- Object.prototype.toString.call
- 可以識別標準類型和內(nèi)置對象類型
- 不能識別自定義對象類型
- Object.prototype.toString.call(123) === 'Number'
- constructor
- 可以判別準備類型、內(nèi)置對象類型、自定義對象類型
- 不能判別null,Undefined
- (1).constructor === Number
function getConstructorName(obj){
return ( obj === undefined || obj === null )? obj+'' : obj.constructor.toString().match(/function\s*([^(]*)/)[1];
}
- getConstructorName(null) --> null
- getConstructorName(new Date()) --> 'Date'
函數(shù)
//函數(shù)聲明
function foo(){}
//函數(shù)表達式
var foo = function(){};
//函數(shù)實例化
var foo = new Function('i','console.log(1);');
//變量、函數(shù)聲明前置:
//function
console.log(foo);
//undefined
console.log(bar);
function foo(){}
var bar = function(){};
js作用域:對象、函數(shù)有獨立作用域
函數(shù)調用方式
Function.prototype.apply(this, [])
Function.prototype.call(this, ...args)
//保存函數(shù)的參數(shù),以便直接調用
var fooCopy = foo.bind(this, ..args);
fooCopy();
arguments
arguments是一個Array-like對象
閉包
- 相當于一個對象,內(nèi)部可以維護成員變量和成員函數(shù)
原型vs類
- 類是抽象概念,java中用類構造對象。
- 原型是一個對象(Function),js中用對象(Function)構造對象。
設置對象的原型
- Object.create(proto);
- 傳入一個原型,返回一個對象
var Car = {
start: function(){
console.log('start');
}
}
var landRover = Object.create(Car);
//'start'
landRover.start();
- 使用構造函數(shù)構造對象,使用prototype設置原型
var Car = function(){
}
Car.prototype.start = function(){
console.log('start');
}
var landRover = new Car();
//'start'
landRover.start();
原型鏈繼承
//Car構造函數(shù)
var Car = function(){
}
Car.prototype.start = function(){
console.log('start');
}
//LandRover構造函數(shù)
var LandRover = function(){
}
LandRover.prototype = new Car();
var landRover = new LandRover();
//start
landRover.start();
obj.hasOwnProperty(name);
- 對象自身是否有該屬性
構造函數(shù)的原型鏈
Car --> Function --> Object
LandRover --> Function --> Object
- 因為Car和LandRover都是函數(shù)(Function)的實例,所以可以訪問Function的原型方法,即Function.prototype的方法,即Car.proto = Function.prototype
- Function是Object的實例,所以可以訪問對象的原型方法,即Object.prototype的方法
JS變量作用域
- JS使用靜態(tài)作用域
var x = 10;
function foo(){
console.log(x);
}
function bar(){
var x = 20;
foo();
}
//10
bar();
- JS沒有塊級作用域,只有全局作用域和對象(函數(shù))作用域
- ES5中使用詞法環(huán)境管理靜態(tài)作用域(使用outer指向外層環(huán)境,內(nèi)層函數(shù)可以訪問外層變量)
- with關鍵字可以創(chuàng)建臨時環(huán)境
var obj = {foo:'bar'};
with(obj){
//'bar'
console.log(foo);
}
聲明函數(shù)與函數(shù)表達式
- 聲明函數(shù)會被提前定義,他的作用域為靜態(tài)作用域,outer指向全局環(huán)境。
- 函數(shù)表達式在執(zhí)行的時候才會被創(chuàng)建,他的作用域為動態(tài)作用域,outer指向當前環(huán)境。
帶名稱的函數(shù)表達式
- 執(zhí)行該表達式的時候,會動態(tài)創(chuàng)建一個作用域,使得在函數(shù)內(nèi)可以使用A來訪問該函數(shù)。
- 在函數(shù)外并不能訪問到A
(function foo(){
//foo并沒有被修改
foo = 1;
//function
console.log(foo);
})();
//error
console.log(foo);
使用函數(shù)表達式創(chuàng)建閉包
- 利用函數(shù)表達式的作用域特性,可以創(chuàng)建閉包(內(nèi)部函數(shù)訪問外部函數(shù)的變量)。
function foo(){
var i = 0;
return function(){
console.log(i++);
}
}
var bar = foo();
//0
bar();
//1
bar();
閉包的應用
- 保存現(xiàn)場(變量的值、狀態(tài)等)
//錯誤實例
function addHandlers(nodes){
for(var i=0; i<nodes.length;i++){
nodes[i].onclick = function(){
//當函數(shù)執(zhí)行的時候,i已經(jīng)變成了nodes.length,所以所有的node都會打印nodes.length
console.log(i);
}
}
}
//使用閉包
function addHandlers(nodes){
//每調用一次helper,都會創(chuàng)建一個閉包,保存i的值
function helper(i){
return function(){
//0 1 2 3
console.log(i);
};
}
for(var i=0;i<nodes.length;i++){
nodes[i].onclick = helper(i);
}
}
- 封裝(信息隱藏,提供接口)