null
,undefined
,boolean
,number
,string
,symbol
(es6)。Object
var a = 1; 分配一塊內存#001,存放值爲1,a存放值1
var b = a; 分配一塊內存#002,存放值爲1,b存放值1
console.log(a); 1
console.log(b); 1
兩個值互不影響
var a = []; 分配一塊內存#001,存放值爲[], a存放地址#001
var b = a; 將地址#001賦值給b,此時b的地址也是#001,a和b表明同一個地址
a.push(1)
console.log(a); [1]
console.log(b); [1]
同一個地址表明同一個地方,因此會互相影響
複製代碼
function test(person) {
person.age = 26 // 這裏參數傳入的是對象的地址
person = { // 這裏從新賦值了,至關於從新分配了地址
name: 'yyy',
age: 30
}
return person
}
const p1 = {
name: 'yck',
age: 25
}
const p2 = test(p1)
console.log(p1) // -> {name: 'yck', age: 25 }
console.log(p2) // -> {name: 'yyy', age: 30 }
複製代碼
typeof
對於基本類型,除了 null
均可以顯示正確的類型,對於對象沒法區分是哪種es6
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof b // b 沒有聲明,可是還會顯示 undefined
複製代碼
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
複製代碼
對於 null
來講,雖然它是基本類型,可是會顯示 object
算法
typeof null // 'object'
複製代碼
instanceof
區分對象instanceof
是經過原型鏈來判斷json
const Person = function() {}
const p1 = new Person()
p1 instanceof Person // true
var str = 'hello world'
str instanceof String // false
var str1 = new String('hello world')
str1 instanceof String // true
複製代碼
JS不存在整型,所有按照 IEEE 754 雙精度版本(64位)來表示數字 而計算機計算是採用二進制,因此會將十進制先轉成2進制計算後再轉成十進制,所以計算有時會出現偏差,好比:0.2 + 0.1 = 0.30000000000000004數組
console.log(NaN == NAN);//false
console.log(typeof NaN); //'number'
複製代碼
console.log( isNaN(NaN) ); //true
console.log( isNaN(10) ); //false
console.log( isNaN(true) ); //false
複製代碼
在 JS 中類型轉換隻有三種狀況,分別是:bash
在條件判斷時,undefined, null, false, NaN, '', 0, -0,轉爲 false,其餘全部值都轉爲 true。閉包
對象在轉換類型的時候,會調用內置的 [[ToPrimitive]] 函數,對於該函數來講,算法邏輯通常來講以下:app
若是已是原始類型了,那就不須要轉換了函數
let a = {
valueOf() {
return 0
},
toString() {
return '1'
},
[Symbol.toPrimitive]() {
return 2
}
}
1 + a // => 3
複製代碼
Number():字符串--整數 (能夠用於任何類型總體轉換)
Number(true)--1
Number(false)-0
Number(null)--0
Number([ ])---0
Number(' ')---0
Number([ 12])---12
Number('100')--100
Number('01000')---1000
轉不了的就返回NaN
Number('hello world')----NaN
Number(undefined)----NaN
Number([ 1,2,3])---NaN
Number(json)---NaN json轉不了
Number(function(){} ...window等)---NaN
不能轉換含有非數字的東西:Number(100px)--NaN
因爲Number()函數在轉換字符串比較複雜且不夠合理,所以處理整數通常用parseInt()
複製代碼
parseInt() parseFloat (只針對字符串) parseInt(一個一個的轉換,若是第一個不是數字就轉成NaN,只能轉字符串類型,) parseInt(字符串,幾進制(默認10進制))學習
parseInt(100px)---100
parseInt(10px23)--10
parseInt(+100px)--100(忽略+,-,空格,0000)
parseInt(0100)---100
parseInt(12.2元)--12
parseInt('')--NaN
parseFloat(只認識第1個小數點)
parseFloat(12.32元)--12.32
parseFloat(12.3.2元)--12.3
if(parseInt(num)==parseFloat(num)) 說明num是整數
複製代碼
1 + '1' // '11'
true + true // 2
4 + [1,2,3] // "41,2,3"
複製代碼
另外對於加法還須要注意這個表達式 'a' + + 'b'ui
'a' + + 'b' // -> "aNaN"
複製代碼
由於 + 'b' 等於 NaN,因此結果爲 "aNaN",你可能也會在一些代碼中看到過 + '1' 的形式來快速獲取 number 類型。
那麼對於除了加法的運算符來講,只要其中一方是數字,那麼另外一方就會被轉爲數字
4 * '3' // 12
4 * [] // 0
4 * [1, 2] // NaN
複製代碼
若是是對象,就經過 toPrimitive 轉換對象 若是是字符串,就經過 unicode 字符索引來比較
let a = {
valueOf() {
return 0
},
toString() {
return '1'
}
}
a > -1 // true
複製代碼
在以上代碼中,由於 a 是對象,因此會經過 valueOf 轉換爲原始類型再比較值。
Array
push():在末尾添加1項,並返回新數組的長度
pop(); 從末尾刪除1項,並返回刪除的那一項
shift(); 從前面刪除1項,並返回刪除的那一項
unshift(); 從前面增長1項,並返回新數組的長度
複製代碼
function compare(v1,v2){
return v2-v1;
}
var value = [1,3,4,0,2];
value.sort(compare)
複製代碼
var num = [1,2,3,4,5];
num.indexOf(4); //3
num.lastIndexOf(4); //1
複製代碼
var num = [1,2,3,4,5];
var result = num.reduce (function(prev,cur,index,array){return prev+cur;} ); 返回的是每項執行結果
alert(result);//15
複製代碼
length:長度
var str = 'hello ';
console.log(str.charAt(0)); // h 返回單個字符
console.log(str.charCodeAt(1)); //101 返回字符編碼
console.log(str[0]); //h 可直接經過下標
console.log(str.concat('liujingyi'));//hello liujingyi
console.log(str.concat('liu',' jing'));//hello liu jing
console.log(str+'ljy'); //hello ljy
複製代碼
var str = 'abjcdefj';
console.log(str.slice(2)); //jcdefj' 開始位置,結束位置 第二個參數默認到最後 console.log(str.substring(2)); //jcdefj' 開始位置,結束位置 第二個參數默認到最後
console.log(str.substr(2)); //jcdefj' 開始位置,返回的字符個數 第二個參數默認到最後 console.log(str.slice(2,5)); //jcd console.log(str.substring(2,5));//jcd console.log(str.substr(2,5)); //jcdef 複製代碼
var text = "cat,bat,sat,fat";
var result1 = text.match('at');
var result2 = text.match(/at/);
console.log(result1); //["at", index: 1, input: "cat,bat,sat,fat"]
console.log(result2); //["at", index: 1, input: "cat,bat,sat,fat"]
複製代碼
var text = "cat,bat,sat,fat";
var result1 = text.search('at');
var result2 = text.search(/at/);
alert(result1); //1
alert(result2); //1
複製代碼
var text = "cat,bat,sat,fat";
var result = text.replace("at","ond");
alert(result); //"cond,bat,sat,fat"
var text = "cat,bat,sat,fat";
var result = text.replace(/at/g,"ond");
alert(result); //"cond,bond,sond,fond"
複製代碼
var text = "cat,red,dog";
var result1 = text.split(',');// ["cat", "red", "dog"]
var result2 = text.split(); // ["cat,red,dog"]
var result3 = text.split(',',2); // ["cat", "red"]
複製代碼
var text = "dog";
var result1 = text.localeCompare('dog');//0
var result2 = text.localeCompare('cat'); // 1
fromCharCode():傳入編碼,返回字符串
var result1 = String.fromCharCode(104,101,108,108,111); //hello
substr 參數:截取的起始位置 和長度(若是省略截取到最後)
var str="Hello world!";
var n=str.substr(2,3)
n 輸出結果:
llo
複製代碼
<script>
var str="Hello world!";
document.write(str.substring(3)+"<br>");
document.write(str.substring(3,7));
</script>
以上代碼輸出結果:
lo world!
lo w
複製代碼
Date對象
var date = new Date();
var year = date.getFullYear();
var month = end(date.getMonth()+1);
var dates = end(date.getDate());
var hours = end(date.getHours()+1);
var minutes = end(date.getMinutes()+1);
var seconds = end(date.getSeconds()+1);
var dayList=['星期日','星期一','星期三','星期四','星期五','星期六'];
var day = dayList[date.getDay()];
var time = year+':'+month+':'+dates+':'+hours+':'+minutes+':'+seconds+':'+day;
console.log(time);
function end(time){
return time<10?'0'+time:time;
}
複製代碼
每一個函數都有一個 prototype 屬性,存放constructor(建立該函數的構造函數) 和 __proto__
每一個對象都有__proto__
屬性,指向了建立該對象的構造函數的原型。其實這個屬性指向了 [[prototype]],可是 [[prototype]] 是內部屬性,咱們並不能訪問到,因此使用 _proto_
來訪問。
對象能夠經過 __proto__
來尋找上一層的屬性,__proto__
將對象鏈接起來組成了原型鏈。
function Fun() {
}
Fun.prototype = {
constructor: f Func(),
__proto__: Object
}
Object.prototype = {
constructor: f Object()
}
var a = new Func()
a.__proto__ 指向Fun.prototype
Fun.prototype.__proto__指向Object.prototype
複製代碼
function create() {
// 建立一個空的對象
let obj = new Object()
// 得到構造函數
let Con = [].shift.call(arguments)
// 連接到原型
obj.__proto__ = Con.prototype
// 綁定 this,執行構造函數
let result = Con.apply(obj, arguments)
// 確保 new 出來的是個對象
return typeof result === 'object' ? result : obj
}
複製代碼
一個函數嵌套另外一個函數的時候,子函數能夠訪問到外部函數的變量,此時就造成了一個閉包,外部函數的變量不會被銷燬。
使用閉包的同時比較容易造成循環引用,若是閉包的做用域鏈中保存着一些 DOM 節點,這時候就有可能形成內存泄露。 若是要解決循環引用帶來的內存泄露問題,咱們只須要把循環引用中的變量設爲 null便可。