前端筆記——JS基礎(原型&&原型鏈)

JavaScript基礎 —— 原型&&原型鏈

構造函數

function Foo(name, age) {
    this.name = name;
    this.age = age;
    this.class = 'class-1';
    //return this ; //默認有這一行
  }
  var f = new Foo('張三', 22);
  var f1 = new Foo('李四', 29);

構造函數 - 擴展

var a={} 實際上是 var a=new Object() 的語法糖
  var a=[] 實際上是 var a=new Array() 的語法糖
  function Foo() {....} 實際上是 var Foo=new Function(...)
  使用 instanceof 判斷一個函數是不是一個變量的構造函數

原型規則和示例

  • 全部的引用類型(數組、對象、函數),都具備對象屬性(便可自有擴展的屬性),null除外
  • 全部的引用類型(數組、對象、函數),都有一個 __proto__ 屬性(隱式原型),屬性值是一個普通的對象
var obj = { };
  obj.x=100;
  console.log(obj.__proto__);
  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
  var arr = [];
  arr.x = 200;
  console.log(arr.__proto__);
  // [constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]
  function fn() {};
  fn.x = 300;
  console.log(fn.__proto__);
  // ƒ () { [native code] }
  var d = null;
  console.log(d.__proto__);
  // Uncaught TypeError: Cannot read property '__proto__' of null
  • 全部的 函數 ,都有一個 prototype 屬性(顯式原型),屬性值也是一個普通對象
console.log(fn.prototype);
  // {constructor: ƒ}
  • 全部的引用類型(數組、對象、函數), __proto__ 屬性值指向它的構造函數的 prototype 屬性值
console.log(obj.__proto__ === Object.prototype);
  // true
  • 當視圖獲得一個對象(全部的引用類型)的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的 __proto__ (即它的構造函數的 prototype )中尋找。
// 構造函數
  function Foo(name, age) {
    this.name = name;
  }
  Foo.prototype.alertName = function() {
    console.log('alertName' + this.name);
  }
  // 建立示例
  var f = new Foo('張三');
  f.prientname = function() {
    console.log('prientname' + this.name);
  }
  // 測試
  f.prientname(); // prientname張三
  f.alertName(); // alertName張三

原型鏈

// 構造函數
  function Foo(name, age) {
    this.name = name;
  }
  Foo.prototype.alertName = function() {
    console.log('alertName' + this.name);
  }
  // 建立示例
  var f = new Foo('張三');
  f.prientname = function() {
    console.log('prientname' + this.name);
  }
  // 測試
  f.prientname(); // prientname張三
  f.alertName(); // alertName張三

  f.toString(); // "[object Object]" 在f.__proto__.__proto__中查找,即Object的顯式原型中尋找

圖片描述

instanceof

  • instanceof 用於判斷 引用類型 屬於哪一個 構造函數 的方法
// f的 __proto__ 一層一層網上找,找到對應的 Foo.prototype
  f instanceof Foo //true
  f instanceof Object //true

q:如何準確判斷一個變量是數組類型

var arr=[]
  // 能夠正確判斷的狀況
  arr instanceof Array //true
  Object.prototype.toString.call(arr) // "[object Array]"
  Object.prototype.toString.apply(arr) // "[object Array]"
  Array.isArray(arr) // true
  // 不能判斷的狀況
  typeof arr // object 是沒法判斷是不是數組的
  // 不許確
  arr.constructor === Array //true 可是原型鏈能夠被改寫,這樣判斷不安全
// 擴展 兼容老版本瀏覽器,isArray的寫法
  if(!Array.isArray){
    Array.isArray = function(arg){
      return Object.property.toString.call(arg) === '[object Array]'
    }
  }

q:寫一個原型鏈繼承的例子

function Elem(id) {
    this.elem = document.getElementById(id);
  }
  Elem.prototype.html = function(val) {
    var elem = this.elem;
    if (val) {
      elem.innerHTML = val;
      return this; // 後續的鏈式操做
    } else {
      return elem.innerHTML;
    }
  }
  Elem.prototype.on = function(type, fn) {
    var elem = this.elem;
    elem.addEventListener(type, fn);
    return this;
  }
  var main = new Elem('main')
  main.html('<p>Hello World</p>').on('click', function() {
    alert('Hello javascript')
  })

q:描述 new 一個對象的過程

  • 建立一個對象
  • this 指向這個新對象
  • 執行代碼,即對 this 賦值
  • 返回 this
function Foo(name, age) {
    this.name = name;
    this.age = age;
    this.class = 'class-1';
    //return this ; //默認有這一行
  }
  var f = new Foo('張三', 22);
  var f1 = new Foo('李四', 29);
相關文章
相關標籤/搜索