如何将instanceof实现为接收字符串的函数?

时间:2013-02-24 00:22:52

标签: javascript inheritance prototypejs requirejs circular-dependency

我想得到这样的东西

var isChild = isInstanceOf( var1, 'Constructor')

应该等同于

var isChild = (var1 instanceof Constructor)

问题是我没有范围内可用的函数构造函数,所以我想传递一个字符串。

我想我应该遍历原型链以获得constructor.toString()然后进行比较,但我不知道如何实现它。

-

我将完成一些上下文,主要是因为我找到了更好的解决方案

我在两个函数构造函数之间有一个循环引用,并且当我尝试引用它时,RequireJS保持返回undefined。 (在上面的例子中,构造函数将是未定义的。)

我发现了这条信息:http://requirejs.org/docs/api.html#circular

这是导致问题的代码:

//(in BaseControl.js)

define(['src/utils/models/Field'], 
  function(Field) {
[...]

  setField: function(field) {

    if (!field instanceof Field) throw new Error('field should be an instance of Field');
    [...]

问题是Field还需要BaseControl,所以在这种情况下Field未定义,我收到以下错误:

Uncaught TypeError: Expecting a function in instanceof check, but got false 

我可以在requireJS文档之后解决它:

define(['require', 'src/utils/models/Field'], 
  function(require, Field,) {
[...]

  setField: function(field) {

    if (!Field) Field = require('src/utils/models/Field');

    if (!field instanceof Field) throw new Error('field should be an instance of Field');
    [...]

2 个答案:

答案 0 :(得分:1)

你可以尝试

function isInstanceOf(obj, constrname) {
    do {
        if (Object.prototype.hasOwnProperty.call(obj, "constructor")
          && typeof obj.constructor === "function"
          && obj.constructor.name == constrname )
            return true;
    } while (obj = Object.getPrototypeOf(obj))
    return false;
}

...使用非标准name property命名函数对象。


然而,这不会可靠地起作用。既不需要IE支持name属性,也不能使用匿名函数(这些是常见的)。因此,如果您没有要检查的构造函数(出于模块化或其他原因),您应该尝试Duck typing。看看http://zidan.me/javascript-interfaces/也是如此。 Interface实现可以在 Pro JavaScript设计模式,第2章接口Google Books)一书中找到。

答案 1 :(得分:0)

根据您的上述说明,我编写了以下简短代码,并附带相关示例:

    <SCRIPT LANGUAGE="javascript" TYPE="text/javascript">
function _check_data_type( _obj, _datatype )
{
    if ( _obj == null || _obj == "undefined" ) return -1 ;
    var _constructor = _obj.constructor + "" ;
    return ( typeof _obj === _datatype.toLowerCase() ||
             ( _constructor.toLowerCase().indexOf( _datatype.toLowerCase() ) != -1 ) ) ? 1 : 0 ;
}

    var _str1 = new String( "woow" );
    var _str2 = "woow" ;
    var _pi = 3.14 ;

    function myobj()
    {
        this.contents = "The apple is on the table" ;
    }

    var _array = new Array( 1, 2, 3, 4 ) ; 
    var _myobj = new myobj();

    document.write( "Casting the string 'woow' via object assignment: " + " >> " + ( _check_data_type( _str1, "string" ) ? "It's string" : "Not a string" ) + "<br>" ) ;
    document.write( "Casting the string 'woow' via literal assignment: " + " >> " + ( _check_data_type( _str2, "string" ) ? "It's string" : "Not a string" ) + "<br>" ) ;
    document.write( "is PI a number? " + " >> " + ( _check_data_type( _pi, "number" ) ? "Yes, it is" : "No !" ) + "<br>" ) ;
    document.write( "Is this an object of mine ? " + " >> " + ( _check_data_type( _myobj, "myobj" ) ? "Yes, it's yours, see contents : '" + _myobj.contents + "'" : "No !" ) + "<br>" ) ;
    document.write( "Is this an array obj? " + " >> " + ( _check_data_type( _array, "array" ) ? "Yes, it's an array" : "No !" ) + "<br>" ) ;
    </SCRIPT>
相关问题