[筆記]Javascript中的11個難以理解的問題

看了這個人的javascript系列, 很受教育, 做了一些筆記.

http://www.cnblogs.com/fool/tag/%E7%90%86%E8%A7%A3Javascript/

  1. 原始值與引用值
    原始值存放在棧裏, 引用值存放在堆裏. 如程序:
    function Person(id,name,age){
    	this.id = id;
    	this.name = name;
    	this.age = age;
    }
    
    var num = 10;
    var bol = true;
    var str = "abc";
    var obj = new Object();
    var arr = ['a','b','c'];
    var person = new Person(100,"笨蛋的座右銘",25);

  2. undefined和null
    undefined: 變量未定義; 是Undefined類型的專屬值;
    null:引用未分配; 是Null類型的專屬值.
    typeof(undefined) == undefined;
    typeof(null) == object;
    undefined==null;
    undefined!==null;
    null instanceof Object == false;
    undefined instanceof Object == false;
    雖然有Undefined和Null類型, 但是通過下面的例子說明這兩個類型是不可見的, 也就是說我們只能使用他們的值:
    alert(undefined instanceof Undefined);
    alert(null instanceof Null);
  3. 僞數組
    特點: 1) 具有length屬性; 2) 像數組一樣按索引順序存取數據; 3) 不具備數組特有的操作數據的方法如push, pop, slice...
    僞數組都可以通過Array.prototype.slice轉換爲真正的數組:
    var faceArray = {0: 'a', 1: 'b', length: 2}//標準的僞數組;
    var realArray = Array.prototype.slice.call(fakeArray);
    js中的僞數組:arguments, node.childNodes, document.getElementsByTagName()...
    IE中的問題 : IE中node.childNodes是不能用slice轉化的.
    Jquery中的僞數組 : Jquery本身就是一個僞數組:
    alert($('.class1').length); alert($('.class1').[0].tagName);
  4. 關於簡單類型的字面量
    var a = 1; b = true, c = "ccc";
    字面量看起來有類型
    alert(typeof a);//number
    alert(typeof b);//boolean
    alert(typeof c);//string
    但是通過instanceof卻測不出來
    alert(a instanceof Number)//false
    alert(a instanceof Object)//false
    alert(b instanceof Boolean)//false
    alert(b instanceof Object)//false
    alert(c instanceof String)//false
    alert(c instanceof Object)//false
  5. 函數的prototype屬性和對象實例的內部prototype屬性
    每個function(構造函數)都有一個prototype屬性, 每個對象實例都有一個不可見的(mozilla把它公開了, 可以通過__proto__來取得)內部的prototype屬性, 它指向構造函數的prototype屬性. prototype還可以有它自己的prototype屬性, 這構成了prototype鏈,  Object是最頂的對象, 所以所有的prototype鏈最終會指向Object.prototype. 當訪問對象實例的屬性/方法的時候, 從對象實例自己開始搜索, 若果搜索不到, 沿着prototype鏈向上搜索, 直到Object.prototype.prototype == null 爲止.
  6. 構造函數的一個小祕密
    var s = new function(){return "sss"};
    alert(s);//[object Object]
    s = new function(){return new String("sss")};
    alert(s);//sss
    關於這段代碼的解釋:
    只要 new 表達式之後的 constructor 返回(return)一個引用對象(數組,對象,函數等),都將覆蓋new創建的匿名對象,如果返回(return)一個原始類型(無 return 時其實爲 return 原始類型 undefined),那麼就返回 new 創建的匿名對象.

  7. 對象的創建的過程
    function Person(name){
            this.name = name;   
    }
    Person.prototype = {
            getName: function(){return this.name}   
    };

    var p = new Person('zhangsan');
    解密p的創建過程:
    • 創建一個build-in object對象obj並初始化;
    • 將p的內部[[Prototype]]指向Person.prototype;
    • 將p作爲this,使用arguments參數調用Person的內部[[Call]]方法, 即執行Person函數體, 並返回返回值, 如果沒有return, 則返回undefined;
    • 如果前一步返回的是Object類型, 則返回這個值給p, 否則返回obj.
  8. 對象的自有屬性和繼承屬性
    function Person(name){
            this.name = name;   
    }
    Person.prototype = {
            type: 'human',
            getName: function(){return this.name}   
    };
    var p = new Person('zhangsan');
    alert(p.hasOwnProperty('type'));//false
    p.type = 'ren';
    alert(p.hasOwnProperty('type'));//true
    運行結果很明確,對象的屬性無法修改其原型中的同名屬性,而只會自身創建一個同名屬性併爲其賦值。
  9. 函數對象的創建過程
    創建一個build-in object對象fn;
    將fn的內部[[Prototype]]設爲Function.prototype;
    設置內部的[[Call]]屬性,它是內部實現的一個方法,處理函數調用的邏輯。(簡單的理解爲指向函數體);
    設置fn.length爲funArgs.length,如果函數沒有參數,則將fn.length設置爲0;
    fn.prototype的constructor指向fn自己;
    返回fn.
  10. instanceof的原理
    查看a是不是B的實例, 就是看B的prototype(構造函數的prototype屬性)指向的對象在不在a的原形鏈上.
  11. 關於Function和Object的猜測
    alert(Function instanceof Function);//true
    alert(Function instanceof Object);//true  
    alert(Object instanceof Function);//true
    alert(Object instanceof Object);//true
    想了好久, 沒有想透......

發佈了174 篇原創文章 · 獲贊 28 · 訪問量 92萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章