objective-c 对象可以用作 Javascript 对象的原型吗?
Can an objective-c object be used as a prototype of Javascript object?
让我们假设在 iOS:
@implementation SomeClass
- (void)sayHello {
NSLog(@"Hello, World!");
}
@end
...
context[@"NativeObject"] = [SomeClass new];
然后在 Javascript:
var test = {};
test.__proto__ = NativeObject;
为什么我检查的时候:
!!NativeObject; //returns true
test.__proto__ === NativeObject; //returns false
test.__proto__ === undefined; //returns true
"sayHello" in test; //returns true
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1; //returns true
既然最后2次测试都暗示有原型,为什么第2次和第3次测试说没有? Javascript核心是否损坏,或者我是否遗漏了有关其实施方式的一些关键信息?
是的,可以。答案来自JSExport
documentation:
In JavaScript, inheritance is supported via a chain of prototype
objects. For each Objective-C class you export, JavaScriptCore creates
a prototype within the enclosing JavaScript context (a JSContext
object). For the NSObject class, the prototype object is the
JavaScript context's Object prototype. For all other Objective-C
classes, JavaScriptCore creates a prototype object whose internal
[Prototype] property points to the prototype property created for the
Objective-C class's superclass. As such, the prototype chain for a
JavaScript wrapper object reflects the wrapped Objective-C type's
inheritance hierarchy.
In addition to the prototype object, JavaScriptCore produces a
JavaScript constructor object for each Objective-C class.
我放了一个 OS X test project on github 来演示它产生以下输出:
!!NativeObject EQUALS true
test.__proto__ === NativeObject EQUALS true
test.__proto__ === undefined EQUALS false
"sayHello" in test EQUALS true
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1 EQUALS true
几点观察:
test.__proto__ === NativeObject
总是 returned true
而你看到它 return false
.
test.__proto__ === undefined
总是 return 编辑 false
而你看到它 return true
。
我还 运行 一个测试,我在其中注释掉了 JSExport 协议,它具有从原型链中删除 SomeClass 的效果,但原型链仍然存在,根据我假设的文档NSObject 的原型:
!!NativeObject EQUALS true
test.__proto__ === NativeObject EQUALS true
test.__proto__ === undefined EQUALS false
"sayHello" in test EQUALS false
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1 EQUALS true
让我们假设在 iOS:
@implementation SomeClass
- (void)sayHello {
NSLog(@"Hello, World!");
}
@end
...
context[@"NativeObject"] = [SomeClass new];
然后在 Javascript:
var test = {};
test.__proto__ = NativeObject;
为什么我检查的时候:
!!NativeObject; //returns true
test.__proto__ === NativeObject; //returns false
test.__proto__ === undefined; //returns true
"sayHello" in test; //returns true
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1; //returns true
既然最后2次测试都暗示有原型,为什么第2次和第3次测试说没有? Javascript核心是否损坏,或者我是否遗漏了有关其实施方式的一些关键信息?
是的,可以。答案来自JSExport
documentation:
In JavaScript, inheritance is supported via a chain of prototype objects. For each Objective-C class you export, JavaScriptCore creates a prototype within the enclosing JavaScript context (a JSContext object). For the NSObject class, the prototype object is the JavaScript context's Object prototype. For all other Objective-C classes, JavaScriptCore creates a prototype object whose internal [Prototype] property points to the prototype property created for the Objective-C class's superclass. As such, the prototype chain for a JavaScript wrapper object reflects the wrapped Objective-C type's inheritance hierarchy.
In addition to the prototype object, JavaScriptCore produces a JavaScript constructor object for each Objective-C class.
我放了一个 OS X test project on github 来演示它产生以下输出:
!!NativeObject EQUALS true
test.__proto__ === NativeObject EQUALS true
test.__proto__ === undefined EQUALS false
"sayHello" in test EQUALS true
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1 EQUALS true
几点观察:
test.__proto__ === NativeObject
总是 returnedtrue
而你看到它 returnfalse
.test.__proto__ === undefined
总是 return 编辑false
而你看到它 returntrue
。
我还 运行 一个测试,我在其中注释掉了 JSExport 协议,它具有从原型链中删除 SomeClass 的效果,但原型链仍然存在,根据我假设的文档NSObject 的原型:
!!NativeObject EQUALS true
test.__proto__ === NativeObject EQUALS true
test.__proto__ === undefined EQUALS false
"sayHello" in test EQUALS false
Object.getOwnPropertyNames(test).indexOf("sayHello") == -1 EQUALS true