前端笔记——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);
阅读 460更新于 2018-06-14
推荐阅读
zangse的博客
用户专栏

个人技术笔记

4 人关注
9 篇文章
专栏主页
目录