亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

你不知道的 javascript【推薦】

 更新時間:2017年01月08日 09:35:43   作者:PeakLeo  
本文介紹了javascript中你所不知道的相關(guān)知識。具有一定的參考價值,下面跟著小編一起來看下吧

一、對象

JavaScript簡單類型有數(shù)字、字符串、布爾值、null、undefined,其他所有的值都是對象(數(shù)組、函數(shù)、正則表達式都是對象)。

數(shù)字、字符串、布爾值雖然擁有方法(包裝對象),但并不是對象。

包裝對象:

每當讀取一個基本類型值的時候,后臺會創(chuàng)建一個對象的基本包裝類型的對象,從而能夠調(diào)用一些方法來操作這些數(shù)據(jù)。

var s1 = 'abcdefg' ;
var s2 = s1.substring(2) ;

后臺自動完成下列處理:

  • 創(chuàng)建String類型的一個實例
  • 在實例上調(diào)用指定的方法
  • 銷毀這個實例

所以上面代碼等同于:

對象字面量

var flight = {
 airline: "Oceanic",
 number: 815,
 departure: {
  IATAL: "SYD",
  time: "2004-09-22 14:55",
  city: "Sydney"
 },
 arrival: {
  IATA: "LAX",
  time: "2004-09-23 10:42",
  city: "Los Angeles"
 }
}

檢索

[] : flight['number']
. : flight.number

更新

通過賦值語句更新,如果屬性名已經(jīng)存在于對象中,則被替換;如果對象中沒有那個屬性名,則添加。

stooge['first-name'] = 'Jerome'

引用

對象賦值通過引用來傳遞,它們永遠不會被拷貝。

var a = {
 name: 'a'
}
var b = a
b.name = 'b'
console.log(a.name)  // b

這里牽扯出 JavaScript 深拷貝和淺拷貝的問題

上例是淺拷貝使用Object.create可以進行深拷貝

var a = {
 name: 'a'
}
var b = Object.create(a)
b.name = 'b'
console.log(a.name)  // a

自定義方法深拷貝見下:

var deepCopy= function(source) { 
 var result={};
 for (var key in source) {
  result[key] = typeof source[key]==='object'? deepCoyp(source[key]): source[key];
 } 
 return result; 
}

此時 var b = deepCopy(a) 得到的 b 就和 a 沒有引用關(guān)系,即修改 b 不會影響 a了

原型

每個對象都連接到一個原型對象,并且從中繼承屬性。所有通過對象字面量創(chuàng)建的對象都連接到 Object.prototype 這個JavaScript中標準的對象。

創(chuàng)建一個對象時,可以選擇某個對象作為它的原型:

var o = {o1:1,o2:function(){alert(1)}}
function F(){}
F.prototype = o
var f = new F()

反射

使用 hasOwnProperty 檢查屬性是否是對象獨有的,它并不會檢查原型鏈。

flight.hasOwnProperty('number');    //true

枚舉

for in 可以遍歷對象中所有的屬性名(見深拷貝部分)

刪除

delete 可以刪除對象屬性,不會觸及原型鏈中的任何對象

減少全局變量污染

最小化使用全局變量的一個方法是創(chuàng)建唯一一個全局變量:

var App = {}
App.stooge = {
 "first-name": "Joe",
 "last-name": "Howard"
}
App.flight = {
 airline: "Oceanic",
 number: 815
}

減少全局變量污染另一個辦法是使用閉包進行信息隱藏

二、函數(shù)

函數(shù)包含一組語句,是Javascript的基礎(chǔ)模塊單元,用于代碼復(fù)用、信息隱藏和組合調(diào)用。

一般來說,所謂編程就是將一組需求分解成一組函數(shù)與數(shù)據(jù)結(jié)構(gòu)的技能。

函數(shù)對象

函數(shù)就是對象,對象是鍵值對的集合并且擁有一個連到原型對象的隱藏連接。對象字面量產(chǎn)生的對象連接到 Object.prototype ,函數(shù)對象連接到 Function.prototype (該原型對象本身又連接到 Object.prototype)。

var add = function(a,b){
 return a + b;
}

函數(shù)表達式包含四部分:

  • 保留字 function
  • 函數(shù)名,可以被省略(匿名函數(shù))
  • 參數(shù),逗號分隔
  • 花括號中的語句

函數(shù)表達式允許出現(xiàn)在任何允許表達式出現(xiàn)的地方,函數(shù)也可以被定義在其他函數(shù)中。一個內(nèi)部函數(shù)可以訪問自己的參數(shù)和變量,同時它也能方便地訪問它被嵌套在其中的那個函數(shù)的參數(shù)和變量。通過函數(shù)表達式創(chuàng)建的函數(shù)對象包含一個連到外部上下文的連接,被稱為閉包。

調(diào)用

函數(shù)在調(diào)用的時候有兩個附加參數(shù):this、arguments。

this 是調(diào)用上下文,值取決于函數(shù)調(diào)用的模式。

1.方法調(diào)用模式

一個函數(shù)被保存為對象的一個屬性時,即為一個方法。當一個方法被調(diào)用時,this 被綁定到該對象。

每個函數(shù)在創(chuàng)建時附有兩個附加的隱藏屬性:

  • 函數(shù)上下文
  • 實現(xiàn)函數(shù)行為的代碼

每個函數(shù)對象在創(chuàng)建時也會帶一個 prototype 屬性,它的值是一個擁有 constructor 屬性且值為該函數(shù)的對象。

函數(shù)表達式

函數(shù)對象可以通過函數(shù)表達式來創(chuàng)建:

var dog = {
 name : 'xxx' ,
 leg:{
  sum : 4 ,
  move:function(){
   console.log(this) ; //Object,是leg對象,而不是dog對象,下面證明了
   alert(this.name) ; //underfined
   alert(this.sum) ; //4
  }
 }
}
dog.leg.move();

2.函數(shù)調(diào)用模式

函數(shù)僅僅當做函數(shù)來調(diào)用時,this 被綁定到全局對象。

var a = 111 ;
function t1(){
 var a = 1
 function t2(){ 
  console.log(this.a) //111,這其實很不合理,應(yīng)該指向t2的。
 }
 t2()
}
t1()

這其實是語言設(shè)計上的一個錯誤,倘若語言設(shè)計正確,當內(nèi)部函數(shù)被調(diào)用時,this 應(yīng)該仍然綁定到外部函數(shù)的 this 變量。

3.構(gòu)造器調(diào)用模式

如果一個函數(shù)前面帶上 new 調(diào)用,那么將創(chuàng)建一個隱藏連接到該函數(shù)的 prototype 成員的新對象,同時 this 將被綁定到那個新對象上。

function Dog(name){
 this.name = name ;
}
Dog.prototype.cry = function(){
 alert(this.name)
}
var dog1 = new Dog('xxx');
dog1.cry(); // 'xxx'

4.Apply/Call調(diào)用模式

apply 接受兩個參數(shù),第一個是將被綁定給this的值,第二個就是一個參數(shù)數(shù)組。

call 與 apply 相同,不過第二個參數(shù)不是數(shù)組。

var dog = {
 leg : 4 ,
 color:'yellow'
}
var color = 'red' ;
function t(){
 alert(this.color) ;
}
t(); // red , 因為指向this在函數(shù)中調(diào)用指向window
t.call(dog); //yellow , 把t()的作用域指向了dog

再來說說 arguments,它是一個類數(shù)組對象(擁有l(wèi)ength屬性,但缺少所有數(shù)組方法)。通過它可以訪問函數(shù)調(diào)用時傳遞給函數(shù)的參數(shù)列表。

返回

一個函數(shù)調(diào)用時,將暫停當前函數(shù)的執(zhí)行,傳遞控制權(quán)和參數(shù)給新函數(shù)。它從第一個語句開始執(zhí)行,并在遇到關(guān)閉函數(shù)體的 } 時結(jié)束。使得函數(shù)把控制權(quán)交還給調(diào)用該函數(shù)的程序部分。

return 語句可用來使函數(shù)提前返回,當 return 執(zhí)行時,函數(shù)立即返回而不再執(zhí)行余下的語句。一個函數(shù)總是會返回一個值,如果沒有指定返回值,則返回 undefined 。

如果函數(shù)前加上 new 來調(diào)用,且返回值不是一個對象,則返回this(該新對象)。

異常

拋出異常

function add(a,b){
 if(typeof a!=='number' || typeof b!=='number'){
  throw {
   name: 'TypeError',
   message: 'add needs numbers'
  }
 }
 return a + b;
}

throw 語句中斷函數(shù)的執(zhí)行,拋出一個 exception 對象,該對象包含可識別異常類型的 name 屬性和一個描述性的 message 屬性。

該 exception 對象將被傳遞到一個 try 語句的 catch 從句

try{
 add('seven')
}catch(e){
 console.log(e.name)
 console.log(e.message)
}

如果在 try 代碼塊中拋出異常,控制權(quán)就跳轉(zhuǎn)到其 catch 從句。

給類型增加方法

Number.prototype.integer = function(){
 return Math[this < 0 ? 'ceiling' : 'floor'](this) //this指向?qū)嵗?
}
var num = 10/3
console.log(num.integer()) ; // 3

作用域

作用域空間那個值變量和參數(shù)的可見性和生命周期,對程序員來說很重要,因為它減少了命名沖突,并且提供了自動內(nèi)存管理。

JavaScript沒有塊級作用域,卻有函數(shù)作用域:定義在函數(shù)中的參數(shù)和變量在函數(shù)外部是不可見的,而且在一個函數(shù)中的任何位置定義的變量在該函數(shù)中任何地方都可見。

下面這個例子與以對象字面量初始化對象不同,通過調(diào)用一個函數(shù)形式去初始化對象,返回一個對象字面量。此函數(shù)定義了一個 val 變量,該變量對 addVal 和 getVal 總是可用的,但函數(shù)的作用域使得其對其他程序來說是不可見的。

// 從設(shè)計模式的角度來說這是模塊模式
var o = (function(){
 var val = 0;
 return {
  addVal: function(){
   val += 1
  },
  getVal: function(){
   console.log(val)
  }
 }
})()

聯(lián)想到之前我做的一個小游戲,是20秒內(nèi)完成任務(wù),使用 restTime 做倒計時變量。后來同事把restTime修改了,成績賊高。最后我就是用這種辦法把 restTime像 val 一樣隱藏了起來。

閉包

作用域的好處是內(nèi)部函數(shù)可以訪問定義它們的外部函數(shù)的參數(shù)和變量(除了this和arguments)。

var o = function(){
 var val = 0;
 return {
  addVal: function(){
   val += 1
  },
  getVal: function(){
   console.log(val)
  }
 }
}
var oo = o()
oo.addVal()
oo.addVal()
oo.getVal() // 2

當調(diào)用 o 時,返回一個包含addVal和getVal的新對象,該對象的引用保存在 oo 中。雖然 o 返回了,但是 oo 的addVal和getVal有訪問 val 的特權(quán),它們可以訪問被創(chuàng)建時所處的上下文,這就是閉包。

模塊

可以使用函數(shù)和閉包來構(gòu)造模塊。模塊是一個提供接口卻隱藏狀態(tài)與實現(xiàn)的函數(shù)或?qū)ο蟆?/p>

具體見『作用域』部分-模塊模式

三、繼承

當一個函數(shù)對象被創(chuàng)建時,F(xiàn)unction 構(gòu)造器產(chǎn)生的函數(shù)對象會運行類似這樣的代碼:

this.prototype = {constructor: this}

每個函數(shù)都會得到一個 prototype 對象,其值是包含一個 constructor 屬性且屬性值為該新函數(shù)對象。該 prototype 對象是存放繼承特征的地方。

四、數(shù)組

區(qū)分數(shù)組和對象

一個常見的錯誤是在須使用數(shù)組時使用了對象,在須使用對象時使用了數(shù)組。其實規(guī)則很簡單:當屬性名是小而連續(xù)的整數(shù)時,用數(shù)組,否則就用對象。

JavaScript中數(shù)組 typeof 返回是 object,這并不能區(qū)分數(shù)組和對象。

var is_array = function(value){
 return value && 
  typeof value === 'object' &&
  typeof value.length === 'number' &&
  typeof value.splice === 'function' &&
  !(value.propertyIsEnumerable('length'))
}
  • 首先,我們判斷這個值是否為真,我們不接受 null 和其他為假的值。
  • 其次,我們判斷這個值的 typeof 運算結(jié)果是否是 object 。對于對象、數(shù)組和null來說,將得到 true。
  • 第三,我們判斷這個值是否有一個值為數(shù)字的 length 屬性,對于數(shù)組是 true ,對于對象則為 false
  • 第四,判斷這個值是否包含一個 splice 方法。對于數(shù)組,返回 true
  • 最后,我們判斷 length 屬性是否是可枚舉的

這真的很復(fù)雜,實際上,我一直是這樣用的,什么類型都能檢測,堪稱萬能:

var toString = Object.prototype.toString
function isObject(obj) {
 return toString.call(obj) === "[object Object]"
}
function isString(obj) {
 return toString.call(obj) === "[object String]"
}
function isArray(obj) {
 return toString.call(obj) === "[object Array]"
}
function isFunction(obj) {
 return toString.call(obj) === "[object Function]"
}

五、方法

Array

concat(item...)

返回一個新數(shù)組,并不會修改原數(shù)組

var a1 = [2,3]
var a2 = [332,12]
console.log( a1.concat(a2) ); //[ 2, 3, 332, 12 ]

join(separator)

把一個 array 構(gòu)造成一個字符串,并用 separator 作為分隔符把它們連接在一起。

pop(item...)

移除數(shù)組中最后一個元素并返回該元素

push(item...)

將一個或多個元素添加到數(shù)組尾部,會修改原數(shù)組

reverse()

反轉(zhuǎn)數(shù)組中元素的順序,會修改原數(shù)組,返回當前數(shù)組

shift()

移除數(shù)組中第一個元素

slice(start,end)

從start開始,到end為止(不包括end,可選,默認值是length)復(fù)制數(shù)組

sort(comparefn)

對數(shù)組中的內(nèi)容排序,并不能給數(shù)字排序,因為默認比較函數(shù)是假定要被排序的元素都是字符串。

比較函數(shù)接受兩個參數(shù),并且如果兩個參數(shù)相等返回0,如果第一個參數(shù)應(yīng)該排在前面,則返回一個負數(shù),如果第二個參數(shù)應(yīng)該排在前面,則返回一個正數(shù)。

// a 比 b小時返回 -1,而且根據(jù)上述規(guī)則 a 會排在前面
// 所以這是從小到大的排序
var arr = [1,123,341,34,123]
arr.sort(function(a,b){
 if(a==b){
  return 0
 }else{
  return a < b ? -1 : 1 
 }
})

splice(start,deleteCount,item...)

splice 從數(shù)組中移除一個或多個元素,并用新的item代替他們。

start是從數(shù)組中移除元素的開始位置,deleteCount是要移除的個數(shù)。

會修改原數(shù)組,返回一個包含被移除元素的數(shù)組。

var arr = [23,3,23,2]
var b = arr.splice(0,1)
console.log(arr)  ;  //[ 3, 23, 2 ]
console.log(b) ;  //[ 23 ]

deleteCount 為0時,則為添加新元素:

var arr = [23,3,23,2]
var b = arr.splice(1,0,'aa')
console.log(arr)  // [ 23, 'aa', 3, 23, 2 ]
console.log(b)  // []

deleteCount 與 item的個數(shù)相等時,則為替換:

var arr = [23,3,23,2]
var b = arr.splice(1,1,'aa')
console.log(arr)  //[ 23, 'aa', 23, 2 ]
console.log(b)  //[ 3 ]

unshift(item...)

將item從數(shù)組頭部插入數(shù)組

Function

apply(thisArg,argArray)

見 『Apply/Call調(diào)用模式』

Number

toFixed(fractionDigits)

把這個 number 轉(zhuǎn)換成一個十進制形式的字符串??蛇x參數(shù) fractionDigits 控制其小數(shù)點后的數(shù)字位數(shù)。

Math.PI.toFixed(); //3
Math.PI.toFixed(2); //3.14
Math.PI.toFixed(4); //3.1415

toPrecision(precision)

同 toFixed ,參數(shù)控制有效數(shù)字的位數(shù)

toString()

將number轉(zhuǎn)換成字符串

Object

hasOwnProperty(name)

只檢查此對象中的屬性,原型鏈中得同名屬性不會被檢查。如果存在此屬性則返回 true。

String

charAt(pos)

返回在字符串中pos處的字符

charCodeAt(pos)

返回不是一個字符串,而是以整數(shù)形式表示的字符碼位

concat(string...)

與其他字符串連接起來構(gòu)造一個新字符串,不常用,因為 + 也能滿足需求

indexOf(searchString,pos)

在字符串內(nèi)查找另一個字符串 searchString,如果被找到,則返回第一個匹配字符的位置,否則返回 -1 。

可選參數(shù) pos 設(shè)置從字符串的某個指定位置開始查找。

lastIndexOf(searchString,pos)

與indexOf類似,不同從末尾開始查找

slice(start,end)

復(fù)制字符串的一部分構(gòu)造一個新的字符串

split(separator,limit)

把字符串分割成片段創(chuàng)建數(shù)組,limit可限制被分割的片段數(shù)量。

一個有意思的技巧:

new Array(11).join('0').split('') //生成10個元素為0的數(shù)組

toLowerCase()

將字符串中所有字母轉(zhuǎn)化為小寫

toUpperCase()

將字符串中所有字母轉(zhuǎn)化為大寫

六、糟粕

這一部分用來吐槽JS這門語言設(shè)計上不周到的地方

全局變量

共三種方法定義全局變量:

  • 脫離任何函數(shù)var語句 var foo = value
  • 直接添加一個屬性到全局對象中,全局對象是所有全局變量的容器。在web中,全局對象是 window : window.foo = value
  • 使用未聲明的變量,這被稱為隱式的全局變量:foo = value

之前說過,可以通過 創(chuàng)建一個全局變量 和 閉包 減少全局變量污染(注意,只是減少,沒辦法避免,總要有暴露出來的變量,不要鉆牛角尖)。

作用域

沒有塊級作用域,只有函數(shù)作用域

自動插入分號

JavaScript 有一個機制,會試圖通過自動插入分號來修正有缺損的程序。它有可能會掩蓋更為嚴重的錯誤。

return
{
 status: true
}

看起來是返回一個對象,但是自動插入分號讓它返回了undefined,這樣可以避免:

return {
 status: true
}

typeof

typeof并不能正確地檢測數(shù)據(jù)類型:

typeof null ; //object

所以使用 Object.prototype.toString.call(null) 這個辦法就好,萬能的!

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

最新評論