ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript は新しいキーワードの実装をどのようにシミュレートしますか? (コード付き)

JavaScript は新しいキーワードの実装をどのようにシミュレートしますか? (コード付き)

不言
不言転載
2018-11-12 16:34:262771ブラウズ

この記事の内容は、JavaScript が新しいキーワードの実装をどのようにシミュレートするかについてです。 (コードを添付します)。困っている友人が参考になれば幸いです。

最近仕事が忙しくてブログの更新が2週間近く空いてしまいましたが、仕事の内容はだいぶ良くなってきましたが、まだまだやるべきことが待っているといつも感じています。私はいつも頭を下げて歩き続けていると感じますが、時々顔を上げて、自分の現状が自分の期待とずれていないか確認する必要があるので、今でも週末にはスターバックスに行って言葉を書くことにしています。 。

今日は、JavaScript での新しいキーワードのシミュレーション実装を記録します。特定の言語の動作をシミュレートする前に、この動作が何をするのかを考える必要があります。これにより、最終的に知識ポイントをよりよく理解できるようになります。候補者の知識の深さを調べるために、面接の質問の多くがシミュレーションの実装について尋ねるのはなぜでしょうか。

function Person(name) {
    this.name = name;
}
var person = new Person('jayChou');
typeof(person)  // "object"
person instanceof Person  // true
person.__proto__ === Person.prototype  // true
person.constructor === Person  //  true
person.constructor === Person.prototype.constructor  // true

上記の内容からわかるように、

  1. new はコンストラクターのインスタンスである新しいオブジェクトを作成して返します

  2. オブジェクト インスタンスのコンストラクター属性は、実際にはコンストラクターのプロトタイプ オブジェクトのコンストラクター属性です。

  3. オブジェクト インスタンスの __proto__ は、コンストラクターのプロトタイプ オブジェクトに関連付けられます。

上記の内容には、JavaScript のプロトタイプ オブジェクトとプロトタイプ チェーンに関する知識が含まれています。十分に理解していない学生は、私の以前のブログを参照してください。

new は JS のキーワードであるため、このキーワードを実装することはできませんが、関数を使用して new キーワードの動作をシミュレートすることはできます。

1. 基本的な考え方

新しいキーワードが何をするのかがわかれば、シミュレーション実装の基本的な考え方がわかります。

/**
 * 模拟实现 JavaScript new 操作符
 * @param  {Function} constructor [构造函数]
 * @return {Object|Function|Regex|Date|Error}      [返回结果]
 */
function mockNew() {
    // 创建一个空对象
    let resultObj = new Object();

    // 取传入的第一个参数,即构造函数,并删除第一个参数。
    let constructor =  Array.prototype.shift.call(arguments);
    
    // 类型判断,错误处理
    if(typeof constructor !== "function") {
        throw("构造函数第一个参数应为函数");
    }
    
    // 绑定 constructor 属性
    resultObj.constructor = constructor;
    
    // 关联 __proto__ 到 constructor.prototype
    resultObj.__proto__ = constructor.prototype;
    
    // 将构造函数的 this 指向返回的对象
    constructor.apply(resultObj, arguments);
    
    // 返回对象
    return resultObj;
}

function Person(name) {
    this.name = name;
}


var person = mockNew(Person, "jayChou");

console.log(person);

// constructor: ƒ Person(name)
// name: "jayChou"
// __proto__: Object

基本的な考え方は正しいです。そこで、新しいキーワードの事前シミュレーションを完了しました。友達は自分で入力して、コードの各文を理解できるかどうかを確認できます。

2. 戻り値の処理

コンストラクターも関数であり、さまざまな種類の戻り値があります。場合によっては、コンストラクターが指定されたオブジェクトのコンテンツを返すため、この部分を処理する必要があります。

/**
 * 模拟实现 JavaScript new 操作符
 * @param  {Function} constructor [构造函数]
 * @return {Object|Function|Regex|Date|Error}      [返回结果]
 */
function mockNew() {
    // 创建一个空对象
    let emptyObj = new Object();

    // 取传入的第一个参数,即构造函数,并删除第一个参数。
    // 关于为什么要用 Array.prototype.shift.call 的形式,见之前的博客文章 《JavaScript之arguments》
    let constructor =  Array.prototype.shift.call(arguments);
    
    // 类型判断,错误处理
    if(typeof constructor !== "function") {
        throw("构造函数第一个参数应为函数");
    }
    
    // 绑定 constructor 属性
    emptyObj.constructor = constructor;
    
    // 关联 __proto__ 到 constructor.prototype
    emptyObj.__proto__ = constructor.prototype;
    
    // 将构造函数的 this 指向返回的对象
    let resultObj = constructor.apply(emptyObj, arguments);
    
    // 返回类型判断, 如果是对象,则返回构造函数返回的对象
    if (typeof resultObj === "object") {
        return resultObj
    }
    
    // 返回对象
    return emptyObj;
}

function Person(name) {
    this.name = name;
    return {
        name: this.name,
        age: 40
    }
}


var person = mockNew(Person, "jayChou");

console.log(person);

// {name: "jayChou", age: 40}
// age: 40
// name: "jayChou"
// __proto__: Object

戻り値がカスタム オブジェクトを返す場合、シミュレートされた新しい関数はカスタム オブジェクトを返します。

概要

JavaScript new キーワードの重要性は、通常の関数が新しいオブジェクトを生成し、オブジェクト インスタンスの __proto__ をプロトタイプ オブジェクトに関連付けられるようにすることです。関数。

この記事には事前知識が必要な箇所もありますが、全体的には比較的簡単に理解できます。

以上がJavaScript は新しいキーワードの実装をどのようにシミュレートしますか? (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。