简单说:JS类、new、prototype与__proto__

302 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

首先一点基本概念

  • 类型是对 JS 中数据的分类
  • JS 中的类型有:数字、字符串、布尔、符号Symbol、null、undefined、对象

一定要区分开!!!!!!!

  • 是对 JS 中对象的分类
  • JS 中的有:对象 Object、数组 Array、函数 Function 等

话不多说直接上代码

首先是借用原型

function Person(name,age){
    this.name=name,
    this.age=age
}
Person.prototype.sayHi=function(){
    console.log('你好,我叫'+this.name)
} 

let person = new Person('cc', 18)
person.name === 'cc' // true
person.age === 18 // true
person.sayHi() // 打印出「你好,我叫 cc」

let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」

然后是class语法

class Person {
  constructor(name,age){
    this.name=name,
    this.age=age
  }
sayHi(){
   console.log('你好,我叫'+this.name)
    }
}

let person = new Person('cc', 18)
person.name === 'cc' // true
person.age === 18 // true
person.sayHi() // 打印出「你好,我叫 cc」

let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」

我们知道,构造函数的优点是:我们可以根据参数来构造不同的对象实例 ,缺点是造成了内存的浪费。所以用构造函数来定义类属性,用原型方式来定义类的方法。这样,我们就既可以构造不同属性的对象,也可以让对象实例共享方法,不会造成内存的浪费。
而上面两种方法本质是一样的,而class语法是ES6新语法==>详情参考:developer.mozilla.org/zh-CN/docs/…

谈一下new

你可知道==>new X()操作帮你做了多少事情?我告诉你:

  • 自动创建一个空对象
  • 自动将该空对象的原型指向 X.prototype(即将 X.prototype 保存的地址复制到空对象.proto 里)
  • 自动将空对象作为 this 来运行构造函数
  • 自动 return this

这里需要说一下 return

默认情况下,没有return的函数的返回值为undefined(即没有定义返回值),如果定义了return,则返回指定对象。
但是构造函数比较特殊,new构造函数在没有return的情况下默认返回新创建的对象。在有return的情况下,需要分为两个情况考虑:

如果返回值为基本数据类型(string,number,boolean,undefined,null),那么返回值为新建对象实例,即this。

var a = function S(){
  this.x=3;
  return 1;
}
var b = new a();
console.log(a); //{x:3}

如果返回值为一个非基本数据类型的对象,函数的返回值为指定的对象,this值所引用的对象被丢弃。\

var a = function S(){
  this.x=3;
  return a;
}
var b = new a();
console.log(b); //S(){this.x=3; return a}

直观的例子:

var a = function User( name, age){
  this.name = name;
  this.age = age;

  // return; // 返回 this
  // return null; // 返回 this
  // return this; // 返回 this
  // return true; // 返回 this
  // return 'string'; // 返回 this
  // return 1; // 返回 this
  // 以上都返回{name:"哈哈",age:18}
  // return []; // 返回 新建的 []
  // return function(){}; // 返回 新建的 function,抛弃 this
  // return new Boolean( false); // 返回 新建的 boolean,抛弃 this
  // return new String( 'hello world'); // 返回 新建的 string,抛弃 this
  // return new Number( 32); // 返回新的 number,抛弃 this
}
var b=new a("哈哈",18)
console.log(b);

谈一下prototype与__proto__

这个你可能听过无数次,也可能用过无数次的东西,折磨,害

prototype 指向一块内存,这个内存里面有共用属性

__proto__ 指向同一块内存

prototype__proto__ 的不同点在于

prototype 是构造函数的属性,而 __proto__ 是对象的属性

难点在于……构造函数也是对象!

如果没有 prototype,那么共用属性就没有立足之地

如果没有 __proto__ ,那么一个对象就不知道自己的共用属性有哪些。