javascript 面向对象 new 关键字 原型链 组织函数

JavaScript面向对象
JavaScript 言语运用组织函数(constructor)作为对象的模板。所谓”组织函数”,就是特地用来天生实例对象的函数。它就是对象的模板,形貌实例对象的基础构造。一个组织函数,能够天生多个实例对象,这些实例对象都有雷同的构造

  1. 组织函数的首字母大写,辨别平常函数。
  2. 函数体内部运用了this关键字,代表了所要天生的对象实例。
  3. 天生对象的时刻,必需运用new敕令。
  4. 组织函数内部运用严厉形式 ‘use strict’,防备当作平常函数挪用,如许就会报错。
function Person(name, age, sex) {
    'use strict';
    this.name = name;
    this.age = age;
    this.sex = sex;
}

Person() 报错
new Person("zhangxc", 29, "male");

1、new关键字 敕令内部完成

function _new(constructor, params) { // 接收个数不确定参数,第一个参数:组织函数;第二个到第n个参数:组织函数通报的参数。
    // 1. 起首将参数构成一个数组 
    // 起首 .slice 这个要领在不接收任何参数的时刻会返回 this 自身,这是一个 Array.prototype 下的要领,因而 this 就是指向挪用 .slice 要领的数组自身。
    var args = Array.prototype.slice.call(arguments); // arguments伪数组,猎取函数的一切参数的伪数组。
    // 等价于
    // [].slice.call(arguments);
    // 2. 猎取组织函数
    var constructor = args.shift(); // shift()返回数组第一个元素
    // 3. 运用组织函数原型建立一个对象。我们愿望以这个现有的对象作为模板,天生新的实例对象,这时候就可以够运用Object.create()要领。
    var context = Object.create(constructor.prototype); // Object.create()参数是一个对象,新建的对象继续参数对象的一切属性
    // 4. 将参数属性附加到对象上面
    var result = constructor.apply(context, args);
    // 5. 返回一个对象
    return (typeof result === 'object' && result != null) ? result : context;
}

function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

var args1 = _new(Person, "zhangxc", 18, "male");

// {name: "zhangxc", age: 18, sex: "male"}

var args2 = new Person("zhangxc", 18, "male");

// {name: "zhangxc", age: 18, sex: "male"}

new.target属性

假如当前函数是new敕令挪用,new.target指向当前函数(组织函数的称号),否则为undefined。

function Test() {
  console.log(new.target === Test);
}

Test() // false
new Test() // true

2、this关键字
this老是指向挪用该要领的对象,在最表面挪用就指向window
bind, call, apply都能够转变this的指向

var name = "window";
var obj = {
    name: "object"
}
function fun() {
    console.log(this.name);
}

1、直接挪用 fun() // window 
由于此时fun() this指向window对象

2、fun.call(obj);    // "object" 
call转变了this的指向,此时this指向obj对象,this.name 在obj对象内里取值,而不是window对象了。

细致解说衔接:https://github.com/mqyqingfen…

3、对象的继续
JavaScript 言语的继续不经由过程 class,而是经由过程“原型对象”(prototype)完成。

prototype原型对象

  1. 每个函数都有一个原型对象
  2. 每个实例对象都有一个 __proto__属性

JavaScript 继续机制的设想头脑就是,原型对象的一切属性和要领,都能被实例对象同享。也就是说,假如属性和要领定义在原型上,那末一切实例对象就可以同享,不仅节省了内存,还表现了实例对象之间的联络。原型对象的作用,就是定义一切实例对象同享的属性和要领。这也是它被称为原型对象的缘由,而实例对象能够视作从原型对象衍生出来的子对象。

// 定义生果组织函数
function Fruit(name, color) {
    this.name = name;
    this.color = color;
}

// 实例化apple对象
var apple = new Fruit("apple", "red");

// 实例化banana 对象
var banana = new Fruit("banana", "yellow");

// 假如他们有配合的属性和要领那末就运用 prototype
// 修正 Fruit组织函数
Fruit.prototype.address = "china";
Fruit.prototype.eat = function() {
    console.log(this.name + "-----" + this.color);
}

apple.addess // china
banana.address // china

apple.eat()  // apple ---- red
banana.eat() // banana ---- yellow


function M1() {
  this.hello = 'hello';
}

function M2() {
  this.world = 'world';
}

**// 1、继续M1,M2本身的属性和要领(hasOwnProperty)**
function S() {
  M1.call(this);
  M2.call(this);
}

**// 2、继续M1原型链上的属性和要领**
S.prototype = Object.create(M1.prototype);
**// 3、继续M2原型链上的属性和要领**
Object.assign(S.prototype, M2.prototype);

// 指定组织函数
S.prototype.constructor = S;

var s = new S();
s.hello // 'hello'
s.world // 'world'

4、原型链
最透辟的原型链解说 哈哈

**1. 每个函数都有prototype属性指向他的原型对象**
**2. 每个对象都有__proto__属性指向他的原型对象**

然后以Date()时候 组织函数为例解说
证实:

var data = new Date();
由于:
data是一个实例对象所以他有__proto__属性指向他的原型对象
Date是一个组织函数所以他有prototype属性指向他的原型对象
所以:Date.prototype == data.__proto__    // Date{} true
data.__proto__是一个对象
由于:javascript划定一切对象都有原型
所以: data.__proto__.__proto__  == Object.prototype // true
这就是原型链了 data.__proto__.__proto__
data对象继续了 Date Object 原型对象的属性和要领。
    原文作者:zxc19890923
    原文地址: https://segmentfault.com/a/1190000018140664
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞