1. 程式人生 > >學習【JavaScript權威指南】(一)

學習【JavaScript權威指南】(一)

不看不得了,一看嚇一跳。。。好多簡單的東西都不懂的,寫個 $(function(){   } );   還需要查詢下才記起來。。。

var book = {
   topic: "Javascript",
   fat: true   //true, false布林值 null為空  undefined為未定義
}
book.author = "why-su"; //通過賦值建立一個新屬性
book.content = {};  //{} 是一個空物件
book.plus = function(){  //定義一個方法
   return this.topic;    //this對自己的引用
} 
book.plus(); //執行方法

關於prototype的理解:https://www.cnblogs.com/loveyoume/p/6112044.html  ( prototype 這個屬性是函式特有的屬性 ,而且是函式的原型物件。對原型物件增加的屬性及其方法,new例項化 之後的物件都能繼承。)

    function Point(x,y) {
        this.x = x;
        this.y = y;
    }
    Point.prototype.z = function () {
        return Math.sqrt(this.x * this.x + this.y*this.y);
    };
    var p = new Point(3,4);  
    alert(p.z());   //結果是 5

隱藏,但保留空間  this.style.visibility = "hidden"

隱藏,不保留空間 this.style.display = "none"

Math的函式多多少少也要給我記住一些:

Math.pow(2,53);   //2的53次方
Math.sqrt(4); //4的平方根
Math.pow(8,1/3); //8的立方根
Math.ceil(.3); //向上取整
Math.floor(.3); //向下取整
Math.ceil(.3); //四捨五入

無窮大 Infinity  負無窮大 -Infinity  負零  -0    

被零整除在JavaScript不報錯,只是返回無窮大Infinity。

零除零是沒有意義的,返回  NaN (非數字值), NaN和任何數都不相等,包括自身,也就是無法使用 x == NaN來判斷x變數是否是NaN,  而要使用  x!=x 來判斷,當且僅當 x 為NaN的時候,表示式才為 true

var y = "one\
        long\
        line";  //一行顯示的話要在每行末尾加上 \ 
var y = "one\long\line";  //如果 找不到\l這個轉義字元的話,\會被忽略

var z = "0123456789";
z.charAt(0);   //第0位的字元
z.substring(2,5);   //索引第2位到第5位 擷取
z.slice(2,5);  //和substring功能一樣
z.slice(-3);  //擷取最後三位
z.indexOf("1");  // 字元1 首次出現的位置
z.indexOf("1",3); //字元1 在 索引3位置之後 首次出現的位置
z.lastIndexOf("1"); //字元1 最後一次出現的位置

注意,字串是固定不變的,類似replace(), toUppserCase() 都返回新字串,原字串本身是不變的。

if(o){
   //o不是false或任何假值(比如null或undefined)
}
if(o != null){
   //o不是 null
}

undefined 是 預定義的全域性變數(和null不一樣,不是關鍵字),它的值就是 未定義,二者都表示值得空缺

null == undefined  //true
null === undefined  //false

===  嚴格相等,如果兩個值都是null或者都是undefined,則它們不相等

 

兩個物件/陣列 是永不相等的,即使含有相同的屬性

型別轉換

"2" * "5"  //結果是10,兩個字串均轉換為10
"2" + "5"  //結果是"25", + 連線字串
var n = 1 - "x";  //x無法轉換為數字,得到的值為  NaN
n + "Object";  //NaN轉為字串 "NaN",得到的值是   "NaNObject"

"1" + 2 //結果是"12",數字轉換為字串後相加
1 + {}  //結果是  "1[object object]"
true + true  //結果是2,布林值轉換為數字後相加
2 +null //結果是2, null轉換為0後相加
2 + undefined //結果是NaN, undefined轉換為NaN後相加

區別:  ==  在判斷前做了 型別轉換, === 未轉換型別

parseInt()  parseFloat()  全域性函式,不屬於任何類的方法

所有物件繼承了2個轉換方法:1,toString()   2,valueOf() 

JavaScript中物件到字串的轉換:先找 toString(),再找 valueOf(), 如果無法獲得一個原始值,則拋型別轉換異常

物件到數字的轉換:先找valueOf()再找 toString(),否則拋異常

var d;  // 未賦值之前,值是 undefined
e;  //報錯,e is not defined
var arr = [0,,,,4];  //包含5個元素,其中三個元素是 undefined
var a1 = [];  //空陣列
var a2 = {};  //空物件
var o = {x:1, y:{z:3}}; //可以使用 o.y.z 或 o["y"]["z"]取值

所有無法轉換為數字的運算元都會轉為 NaN

new Object()
new Object   //建立物件,如果不需要傳任何引數,括號可以省略

JavaScript的所有值不是真值就是假值

11 < 3 //false 數字比較
"11" < "3"  //true, 字串比較
"11" < 3  //false, "11"轉換為數字再進行數字比較
"one" < 3  //false,數字比較,"one"轉換為NaN, >,<,>=,<=只要有一個為NaN,結果都為false

關於eval() : https://blog.csdn.net/u011897392/article/details/58139194

typeof null //為"object"
typeof undefined //為"undefined"
typeof true或false //為"boolean"
typeof 任意數字或NaN  // 為"number"
typeof 字串  //為"string"
typrof 函式  //為"function"

in  

//屬性
var o = {x: 1, y: 2};
"x" in o;  //true, 物件o有屬性x
"toString" in o;  //true 物件繼承了toString()方法

var data = [7,8,9]; 
"0" in data;  //true 如果是陣列,因為是屬性,data[0]為7
0 in data;  //true, 數字轉換為字串
3 in data;  //false, 沒有索引為3的元素

還可以這樣用哈哈 (o゚▽゚)o  

<a href="javascript:void(alert('要死要死'));">連結</a>
var o = new Object(); //建立空物件,和var o = {} 一樣
var o = new Array();
var o = new RegExp("js");

var a= {a0: 0,a1: 1, a2: 2, a3: 3};
//我們知道兩種寫法 a.a0, a["a0"] 都可以獲得值,但以下這種情況只能用a["  "]的寫法
var addr;
for(var i = 0; i < 4; i++){
   addr += a["a"+i] + "\n";
}
    $(function () {
        var o = {x: 1,y: 2};   //o 從 Object.prototype 原型,繼承物件的方法
        var a = inherit(o);   // a 繼承 o 和 Object.prototype
        console.log(a.y);   //2
        a.x = 2;  //覆蓋繼承來的屬性
        console.log(o.x);   //1  原來物件o的屬性沒受到影響
        console.log(a.x);   //2
        a.z = 3;  //屬性賦值要麼失敗,要麼建立一個屬性
        console.log(a.z);   //3

       //如果查不到該屬性
       console.log(o.w);  //返回undefined
       console.log(o.w.length);  //因為null或undefined是沒有屬性的,這裡會報錯
       //簡練的防止報錯的常用方法
       var len = o && o.w && o.w.length;
    })
    function inherit(p){
        if(p == null) throw TypeError();
        if(Object.create){
            return Object.create(p);
        }
        var t = typeof p;
        if(t !== "object" && t !== "function") throw TypeError();
        function f() {};
        f.prototype = p; //屬性賦值要麼失敗,要麼建立一個屬性
        return new f();
    }


var o = {x: 1}
"x" in o;  //true
"y" in o;  //false
"toString" in o; //true o繼承toString屬性

//除了in之外,可以使用 !== (!== 可區分null和undefined,注意不是 !=)
o.x !== undefined    //true
o.y !== undefined    //false
o.toString !== undefined  //true o繼承toString屬性

o.hasOwnProperty("x");   //true
o.hasOwnProperty("y");   //false
o.hasOwnProperty("toString");  //false, 不是物件的自有屬性

//跳過繼承來的屬性
for(p in o){
  if(!o.hasOwnProperty(p)) continue;
}

getter 和 setter

        var p = {
            $n: 1,  //$符號暗示這個屬性是一個私有屬性
            x: 3.0,
            y: 4.0,
            get r() { return Math.sqrt(this.x * this.x + this.y * this.y);},
            set r(newValue){
                var oldValue = Math.sqrt(this.x * this.x + this.y * this.y);
                var ratio = newValue/oldValue;
                this.x *= ratio;
                this.y *= ratio;
            }
        };
        console.log(p.r);    //5
        p.r = 50;
        console.log(p.x +","+p.y); //30,40

序列化物件 serialization是指將物件的狀態轉換為字串,也可將字串還原為物件。

          JSON.stringify() 序列化,JSON.parse() 還原JavaScript物件

陣列:

var a = [];
var b = new Array();   
var c = new Array(10);  //只寫一個引數的話,建立的陣列長度是10,但是沒有任何元素
var d = new Array(5,4,3,2,1,"test","why"); //長度是7
var e = [5,4,3,2,1,"test","why"]; //長度是7

//可以使用 負數或非整數來索引陣列。這種情況下,數值將轉換為“字串”,將“字串”作為屬性名來用
a[-1.23] = true;  //建立名為"-1.23"的屬性
a[1.00] //和 a[1]一樣
a["1000"]  //和a[1000]一樣,如果不存在,則返回 undefined
a[1000] = 1; //賦值新增一個新元素,並且設定length為1001

//JavaScript陣列不存在“越界”錯誤

//稀疏陣列
var a1 = [,,];  //長度是2,但沒有元素
var a2 = [undefined,undefined];
a1[0]  //undefined
a2[0]  //undefined
0 in a1     //false,  在索引0處沒有元素
0 in a2;    //true, 在索引0處有元素

a = [1,2,3,4,5] 
a.length = 0;  //刪除所有的元素,a為[]
a.length = 5;  //長度為5,但沒有任何元素,像new Array(5);

//可以設定length為只讀
Object.defineProperty(a,"length",{writable: false});
//此時再使用 a.length = 0;就不會改變了。

//新增元素
var a = [];
a[5] = "zero";
//或者使用 push
a.push("zerp");   
a.push("zero","one");  //新增2個元素

//刪除元素
var a = [1,2,3,4,5];
delete a[1];         //在索引1位置不再有元素
console.log(1 in a);  //false 索引1位置未在陣列中定義
console.log(a.length);  //5 delete操作不影響陣列長度

a.pop();  //刪除陣列的最後一個元素,長度改變
a.shift(); //刪除陣列的第一個元素,長度改變

//for迴圈
var a = [1,2,3,4,5];
for(var i = 0; i < a.length; i++){
   if(!a[i]) continue;  //跳過null,undefined,不存在的元素
   if(a[!] === undefined) continue;  //跳過undefined
   if(!(i in a)) continue; //跳過不存在的元素
}
//in 會跳過不存在的索引不會被遍歷到
for(var i in a){
   if(!a.hasOwnProperty(i)) continue; //跳過繼承的屬性
   console.log(a[index]);
}

//forEach()方法,按照索引順序遍歷陣列
a.forEach(function(value,index){
   console.log(value);  //value是值,index是索引
});

//join方法將陣列所有元素轉為字串
var a = [1,2,3,4,5];
console.log(a.join());  //1,2,3,4,5  預設用逗號
console.log(a.join("")); //12345
console.log(a.join(" "));  //1 2 3 4 5

a.reverse();  //陣列元素顛倒(在原陣列的基礎上),a變為 [5,4,3,2,1]

//sort排序
var b = ["scd","Ad","por","Fased","gerg","da"];
console.log(b.sort());   //按照字母表順序排序,區分大小寫
console.log(b.sort(function (a,b) {   //自定義排序規則,不區分大小寫,負數排前面
    a = a.toLowerCase();
    b = b.toLowerCase();
    if(a < b) return -1;
    if(a > b) return 1;
    return 0;
}));

//slice擷取陣列,包左不包右, 不會修改原陣列
var a = [0,1,2,3,4,5]; 
console.log(a.slice(0,3)); //[0,1,2]
console.log(a.slice(3));  //[3,4,5]  索引3後的內容
console.log(a.slice(0,-1)); //[0,1,2,3,4]  -1表示倒數第一個
console.log(a.slice(-3,-1)); //[3,4]  -3表示倒數第三個

//splice()會改變原陣列,第一個引數指插入/刪除的起始位置,第二個引數指定 刪除的元素個數,
// 如果省略第二個元素,則從起始點位置後的所有元素都被刪除,返回被刪除的陣列。
var a = [0,1,2,3,4,5,6];
console.log(a.splice(5)); //[5,6]
console.log(a); //[0,1,2,3,4]
console.log(a.splice(1,3));  //[1,2,3]
console.log(a);  //[0,4]
//從第三個引數開始,指定了要加入的元素
console.log(a.splice(1,0,1,2,3));  //[]
console.log(a);  //[0,1,2,3,4]

//every()是指所有元素都必須滿足要求才返回true, some()是隻要有一個元素滿足要求就返回true
var a = [0,1,2,3,4,5,6]; 
console.log(a.every(function (t) { return t<10; })); //true 所有元素都小於10
console.log(a.some(function (t) { return t % 2 === 0; })); //true 至少存在一個元素能被2整除

//reduce按照 從左到右的順序,第二個引數是初始值
var a = [1,2,3];
//初始值是0,按照從左到右順序: 0 + 1 + 2 + 3 = 6
var sum = a.reduce(function (x, y) { return x + y; },0); 
//初始值是1,按照從左到右順序: 1*1*2*3 = 6
var product = a.reduce(function (x, y) { return x * y; },1);
//初始值是0,按照從左到右順序判讀,結果3
var max = a.reduce(function (x, y) { return x > y ? x : y; },0);

//reduceRight() 方法與 reduce()相反,從右至左

JavaScript,函式可以巢狀在其它函式裡面

當呼叫函式的時候傳入的實參比函式宣告時指定的形參個數要少,剩下的形參都將設定為undefined

arguments是指向實參物件的引用,使用下標可以訪問傳入函式的引數

//傳入引數數量不定
function max(){
     var max = Number.NEGATIVE_INFINITY;  //負無窮大
     for(var i = 0; i < arguments.length; i++){
         if(arguments[i] > max) max = arguments[i];
     }
     return max;
}

呼叫 max(-34,-9,-12,-13,-48) 得到最大的 -9

第8章【函式】看的有點暈

//以下建立了10個閉包,但這些閉包都是在同一個函式呼叫中定義的,因此它們可以共享變數i
function constfuncs(){
   var funcs = [];
   for(var i = 0; i < 10; i++){
      funcs[i] = functio(){ return i;};
   }
   return funcs;
}

var funcs = constfuncs();
funcs[5]();   //結果是10,而不是5,這10個閉包的返回值都是10,因為共享了變數i


//需要這樣寫
function constfunc(i){
   return function(){return i;}
}
var funcs = [];
for(var i = 0; i < 10; i++){
  funcs[i] = constfunc(i);
}
funcs[5]();   //結果是5
function check(args){
        var actual = args.length;  //實際傳參個數
        var expected = args.callee.length; //期望的傳參個數
        if(actual != expected)
            throw Error("Expected " + expected + "args; got " + actual);
}

function f(x,y,z){
  check(arguments);
  return x + y + z;
}

f(1)報錯 f(1,2)報錯 f(1,2,3)正確返回6