1 The `proto()` function retrievs or sets the prototype of the given object 2 or resource value. 3 4 Throws an exception if given value does not support setting prototypes. 5 6 When invoked with one argument, returns the prototype of the given value 7 (if any). 8 9 When invoked with two arguments, returns the given value. 10 11 -- Testcase -- 12 {% 13 let fs = require("fs"); 14 15 // create a "class instance" by attaching a function dictionary to 16 // a plain object. 17 let obj = proto({}, { 18 greeting: function(name) { 19 printf("Hello, %s!\n", name); 20 } 21 }); 22 23 // accessing a property on `obj` will look up the prototype chain 24 // if the object itself does not have it 25 obj.greeting("World"); 26 27 printf("%.J\n", [ 28 // retrieve prototype of `fs.file` resource 29 proto(fs.stdout), 30 31 // retrieve prototype of `obj` 32 proto(obj) 33 ]); 34 %} 35 -- End -- 36 37 -- Expect stdout -- 38 Hello, World! 39 [ 40 { 41 "ioctl": "function ioctl(...) { [native code] }", 42 "lock": "function lock(...) { [native code] }", 43 "truncate": "function truncate(...) { [native code] }", 44 "isatty": "function isatty(...) { [native code] }", 45 "error": "function error(...) { [native code] }", 46 "fileno": "function fileno(...) { [native code] }", 47 "flush": "function flush(...) { [native code] }", 48 "close": "function close(...) { [native code] }", 49 "tell": "function tell(...) { [native code] }", 50 "seek": "function seek(...) { [native code] }", 51 "write": "function write(...) { [native code] }", 52 "read": "function read(...) { [native code] }" 53 }, 54 { 55 "greeting": "function(name) { ... }" 56 } 57 ] 58 -- End -- 59 60 61 62 Passing an invalid value throws an exception. 63 64 -- Testcase -- 65 {% 66 proto("inval", {}); 67 %} 68 -- End -- 69 70 -- Expect stderr -- 71 Type error: Passed value is neither a prototype, resource or object 72 In line 2, byte 19: 73 74 ` proto("inval", {});` 75 Near here -----------^ 76 77 78 -- End -- 79 80 -- Testcase -- 81 {% 82 proto({}, "inval"); 83 %} 84 -- End -- 85 86 -- Expect stderr -- 87 Type error: Passed value is neither a prototype, resource or object 88 In line 2, byte 19: 89 90 ` proto({}, "inval");` 91 Near here -----------^ 92 93 94 -- End -- 95 96 97 Setting the prototype of a value to itself is rejected, as it would 98 create a circular prototype chain causing endless loops in lookups. 99 100 -- Testcase -- 101 {% 102 let a = {}; 103 proto(a, a); 104 %} 105 -- End -- 106 107 -- Expect stderr -- 108 Type error: Cannot set circular prototype 109 In line 3, byte 12: 110 111 ` proto(a, a);` 112 Near here ----^ 113 114 115 -- End -- 116 117 118 Setting the prototype of a value to a value in its own prototype chain 119 is rejected as well. 120 121 -- Testcase -- 122 {% 123 let a = {}; 124 let b = {}; 125 126 proto(a, b); 127 proto(b, a); 128 %} 129 -- End -- 130 131 -- Expect stderr -- 132 Type error: Cannot set circular prototype 133 In line 6, byte 12: 134 135 ` proto(b, a);` 136 Near here ----^ 137 138 139 -- End -- 140 141 142 Longer circular chains are rejected as well. 143 144 -- Testcase -- 145 {% 146 let a = {}; 147 let b = {}; 148 let c = {}; 149 150 proto(a, b); 151 proto(b, c); 152 proto(c, a); 153 %} 154 -- End -- 155 156 -- Expect stderr -- 157 Type error: Cannot set circular prototype 158 In line 8, byte 12: 159 160 ` proto(c, a);` 161 Near here ----^ 162 163 164 -- End -- 165 166 167 Reassigning a prototype to a value that is not in its chain remains 168 allowed, including pointing at a former ancestor. 169 170 -- Testcase -- 171 {% 172 let a = {}; 173 let b = { x: 1 }; 174 let c = { y: 2 }; 175 176 proto(a, b); 177 proto(b, c); 178 179 // a -> b -> c, pointing a at c does not create a cycle 180 proto(a, c); 181 182 // b is no longer in a's chain, so a.x is null but a.y resolves 183 printf("%.J\n", [ a.x, a.y ]); 184 %} 185 -- End -- 186 187 -- Expect stdout -- 188 [ 189 null, 190 2 191 ] 192 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt