在 JavaScript 中,什么是替代原型交换?

12

underscore.js的代码中, 注释说明:

// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
  • 什么是代理-原型交换?

或者

  • 在哪里可以找到有关代理-原型交换的文章/清晰文档?

2
我正在阅读Underscore代码,遇到了同样的疑惑。 - Rafael Eyng
2个回答

21

感谢Blender的回答,使得这个翻译成为可能。本文旨在为与我处在同一水平的读者提供便利。

虽然“surrogate-prototype-swapping”不是一个真实的术语,但通过原underscore.js代码的更完整注释,以下是其意图的分解说明。

// A function which will be used as a constructor function in order 
// to add a prototype to a new object. There is nothing special about
// this function, except how it will be used.
var Ctor = function(){};

// Create a shortcut to Object.create if it exists. Otherwise
// nativeCreate will be undefined
var nativeCreate = Object.create;

// An internal function that will use or act as a polyfill for
// Object.create, with some type checking built in.
var baseCreate = function(prototype) {
    // Check if the object passed to baseCreate is actually an object.
    // Otherwise simply return an object (from an object literal), 
    // because there is not a valid object to inherit from.
    if (!_.isObject(prototype)) return {};

    // If Object.create is implemented then return the value
    // returned by Object.create when the prototype parameter is
    // passed into it. If Object.create has already been
    // implemented there is no need to recreate it. Just return
    // its return value.
    if (nativeCreate) return nativeCreate(prototype);

    // If Object.create is not defined then Ctor comes into play.
    // The object passed to baseCreate is assigned to the prototype
    // of Ctor. This means when Ctor is called prototype will be
    // the prototype assigned to this (the keyword this).
    Ctor.prototype = prototype;
    // Because Ctor is called with the new keyword this (the
    // keyword this) is returned returned by Ctor. Thus, the
    // variable 'result' is assigned an object with a prototype
    // equal to baseCreate's parameter 'prototype'.
    var result = new Ctor;
    // Then to reset things Ctor.prototype is set to null.
    Ctor.prototype = null;
    // The newly created object, whose prototype is the object
    // passed to baseCreate is returned.
    return result;
};

8
“代理原型交换”(我怀疑这是否是一个真正的术语)是仅使用对象进行原型赋值的方法。该变量仅被使用一次:
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};

var nativeCreate = Object.create;

// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
    if (!_.isObject(prototype)) return {};

    if (nativeCreate) return nativeCreate(prototype);

    Ctor.prototype = prototype;
    var result = new Ctor;
    Ctor.prototype = null;
    return result;
};

它用于制作一个跨浏览器版本的Object.create。您无法直接创建原型对象的新实例,因此您需要创建一个临时对象,并将其原型设置为您的原型对象,然后返回该对象的新实例。


你回答了我的问题,但为了那些跟随的人我会再详细解释一下。如果我有错,请纠正我。 - anthonynorton
有趣...但我不明白为什么需要使用全局函数引用。你不能在工厂“baseCreate”内部定义function() {}吗? - Joel Cornett
@JoelCornett:同样的原因,他们使用Ctor.prototype = null。这可能会运行得更快? - Blender
有道理。另外,相关链接:http://readystate4.com/2013/10/29/improving-prototypal-inheritance-in-javascript-with-a-surrogate-class/ - Joel Cornett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接