WebKit中自訂JavaScript類型對instanceof語句的處理

來源:互聯網
上載者:User

WebKit中,自行擴充的JavaScript類型需要定義下面的結構體

/*!@struct JSClassDefinition@abstract This structure contains properties and callbacks that define a type of object. All fields other than the version field are optional. Any pointer may be NULL.@field version The version number of this structure. The current version is 0.@field attributes A logically ORed set of JSClassAttributes to give to the class.@field className A null-terminated UTF8 string containing the class's name.@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.@field staticValues A JSStaticValue array containing the class's statically declared value properties. Pass NULL to specify no statically declared value properties. The array must be terminated by a JSStaticValue whose name field is NULL.@field staticFunctions A JSStaticFunction array containing the class's statically declared function properties. Pass NULL to specify no statically declared function properties. The array must be terminated by a JSStaticFunction whose name field is NULL.@field initialize The callback invoked when an object is first created. Use this callback to initialize the object.@field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for the object, and perform other cleanup.@field hasProperty The callback invoked when determining whether an object has a property. If this field is NULL, getProperty is called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value is expensive. @field getProperty The callback invoked when getting a property's value.@field setProperty The callback invoked when setting a property's value.@field deleteProperty The callback invoked when deleting a property.@field getPropertyNames The callback invoked when collecting the names of an object's properties.@field callAsFunction The callback invoked when an object is called as a function.@field hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression.@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression.@field convertToType The callback invoked when converting an object to a particular JavaScript type.@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like getProperty, setProperty, and getPropertyNames. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time.If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this:JSStaticValue StaticValueArray[] = {    { "X", GetX, SetX, kJSPropertyAttributeNone },    { 0, 0, 0, 0 }};Standard JavaScript practice calls for storing function objects in prototypes, so they can be shared. The default JSClass created by JSClassCreate follows this idiom, instantiating objects with a shared, automatically generating prototype containing the class's function objects. The kJSClassAttributeNoAutomaticPrototype attribute specifies that a JSClass should not automatically generate such a prototype. The resulting JSClass instantiates objects with the default object prototype, and gives each instance object its own copy of the class's function objects.A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute.*/typedef struct {    int                                 version; /* current (and only) version is 0 */    JSClassAttributes                   attributes;    const char*                         className;    JSClassRef                          parentClass;            const JSStaticValue*                staticValues;    const JSStaticFunction*             staticFunctions;        JSObjectInitializeCallback          initialize;    JSObjectFinalizeCallback            finalize;    JSObjectHasPropertyCallback         hasProperty;    JSObjectGetPropertyCallback         getProperty;    JSObjectSetPropertyCallback         setProperty;    JSObjectDeletePropertyCallback      deleteProperty;    JSObjectGetPropertyNamesCallback    getPropertyNames;    JSObjectCallAsFunctionCallback      callAsFunction;    JSObjectCallAsConstructorCallback   callAsConstructor;    JSObjectHasInstanceCallback         hasInstance;    JSObjectConvertToTypeCallback       convertToType;} JSClassDefinition;

假設MyObject是我們在C中自訂JavaScript類型的一個對象,並掛載到全域對象下。在網頁中遇到下面的代碼

myObject instanceof MyObject

如果這裡MyObject是個普通對象,即,是以下面的方式定義

JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);JSStringRelease(myObjectIString);

那麼上面的JavaScript語句,執行時將會調用到JSClassDefinition中定義的JSObjectHasInstanceCallback來判斷是否成立;如果JSObjectHasInstanceCallback沒有設定,直接返回false,WebKit不會自行判斷。

如果MyObject是個構造器,即,是以下面的方式定義

JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyObject");JSObjectRef myConstructor = JSObjectMakeConstructor(context, MyObject_class(context), callAsConstructor); //這裡的callAsConstructor與JSClassDefinition中的JSObjectCallAsConstructorCallback屬性功能類似JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL);JSStringRelease(myConstructorIString);

那麼WebKit在遇到instanceof語句時,會自動判斷myObject的類屬性。如果myObject是在JavaScript中用下面的語句建立

var myObject = new MyObject();

或者在C中,通過下面的語句建立

JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);

則判斷為真。(在C中可以通過JavaScriptCore API中的JSValueIsInstanceOfConstructor()獲得同樣的結果)

總結:

  • 如果自訂的JavaScript類型,在構造方面沒有什麼特殊之處,正常返回此自訂類型的對象(通過JSObjectMake建立),則不需要實現JSClassDefinition結構中的JSObjectCallAsConstructorCallback和JSObjectHasInstanceCallback屬性。最方便的辦法是掛載一個自訂類型的構造器到全域對象下。
  • 如果希望自訂的JavaScript類型有一個對象能掛載到全域對象下,同時這個對象還能起到構造器的作用,請同時實現JSClassDefinition結構中的JSObjectCallAsConstructorCallback和JSObjectHasInstanceCallback屬性(通常這意味著JSObjectCallAsConstructorCallback返回的不是簡單的用自訂類型構造出來的對象,通過系統預設的判斷方式無法準確判斷)。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.