[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype":2313,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype":2339},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2309,"stem":2310,"id":2311,"extension":2312},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype","原型与面向对象","JavaScript 以原型链实现对象共享与「继承」；ES6 class 是语法糖。见 语言基础、函数进阶。","技能小册",[12,13],"javascript","prototype","2020-04-13",false,{"type":17,"value":18,"toc":2277},"minimark",[19,22,47,52,61,77,84,100,274,282,297,348,355,361,501,507,510,640,644,648,661,781,785,795,893,897,915,1065,1069,1076,1272,1277,1284,1293,1408,1413,1453,1457,1461,1468,1567,1576,1584,1587,1816,1823,1833,1841,1873,1882,1965,1972,1977,2047,2148,2154,2157,2182,2185,2188,2191,2273],[20,21,8],"h1",{"id":8},[23,24,25,26,30,31,35,36,41,42,46],"p",{},"JavaScript 以",[27,28,29],"strong",{},"原型链","实现对象共享与「继承」；ES6 ",[32,33,34],"code",{},"class"," 是语法糖。见 ",[37,38,40],"a",{"href":39},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fbasics","语言基础","、",[37,43,45],{"href":44},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fadvanced","函数进阶","。",[48,49,51],"h2",{"id":50},"一原型链","一、原型链",[53,54,56,57,60],"h3",{"id":55},"_1-prototype-内部槽位","1. ",[32,58,59],{},"[[Prototype]]"," 内部槽位",[23,62,63,64,66,67,70,71,73,74,76],{},"每个 JavaScript 对象都有一个内部属性 ",[32,65,59],{},"，指向另一个对象（或 ",[32,68,69],{},"null","）。当访问对象的一个属性时，如果对象自身没有，就会沿着 ",[32,72,59],{}," 链条向上查找，直到找到或到达 ",[32,75,69],{},"（原型链的终点）。",[53,78,80,81,83],{"id":79},"_2-prototype-属性","2. ",[32,82,13],{}," 属性",[23,85,86,87,89,90,93,94,96,97,99],{},"函数（尤其是构造函数）拥有 ",[32,88,13],{}," 属性。当通过 ",[32,91,92],{},"new"," 调用该函数创建实例时，实例的 ",[32,95,59],{}," 会指向构造函数的 ",[32,98,13],{}," 对象。",[101,102,107],"pre",{"className":103,"code":104,"language":105,"meta":106,"style":106},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","function Person(name) {\n    this.name = name;\n}\nPerson.prototype.sayHi = function () {\n    console.log(`Hi, I'm ${this.name}`);\n};\nconst p = new Person(\"Alice\");\n\u002F\u002F p.[[Prototype]] === Person.prototype\n","js","",[32,108,109,136,159,165,192,231,237,267],{"__ignoreMap":106},[110,111,114,118,122,126,130,133],"span",{"class":112,"line":113},"line",1,[110,115,117],{"class":116},"sbsja","function",[110,119,121],{"class":120},"sGLFI"," Person",[110,123,125],{"class":124},"sP7_E","(",[110,127,129],{"class":128},"s99_P","name",[110,131,132],{"class":124},")",[110,134,135],{"class":124}," {\n",[110,137,139,143,146,149,153,156],{"class":112,"line":138},2,[110,140,142],{"class":141},"s39Yj","    this",[110,144,145],{"class":124},".",[110,147,129],{"class":148},"su5hD",[110,150,152],{"class":151},"smGrS"," =",[110,154,155],{"class":148}," name",[110,157,158],{"class":124},";\n",[110,160,162],{"class":112,"line":161},3,[110,163,164],{"class":124},"}\n",[110,166,168,172,174,177,179,182,184,187,190],{"class":112,"line":167},4,[110,169,171],{"class":170},"sZMiF","Person",[110,173,145],{"class":124},[110,175,13],{"class":176},"s_hVV",[110,178,145],{"class":124},[110,180,181],{"class":120},"sayHi",[110,183,152],{"class":151},[110,185,186],{"class":116}," function",[110,188,189],{"class":124}," ()",[110,191,135],{"class":124},[110,193,195,198,200,203,206,210,214,217,220,222,224,227,229],{"class":112,"line":194},5,[110,196,197],{"class":148},"    console",[110,199,145],{"class":124},[110,201,202],{"class":120},"log",[110,204,125],{"class":205},"skxfh",[110,207,209],{"class":208},"sjJ54","`",[110,211,213],{"class":212},"s_sjI","Hi, I'm ",[110,215,216],{"class":208},"${",[110,218,219],{"class":141},"this",[110,221,145],{"class":208},[110,223,129],{"class":148},[110,225,226],{"class":208},"}`",[110,228,132],{"class":205},[110,230,158],{"class":124},[110,232,234],{"class":112,"line":233},6,[110,235,236],{"class":124},"};\n",[110,238,240,243,246,248,251,253,255,258,261,263,265],{"class":112,"line":239},7,[110,241,242],{"class":116},"const",[110,244,245],{"class":176}," p",[110,247,152],{"class":151},[110,249,250],{"class":151}," new",[110,252,121],{"class":120},[110,254,125],{"class":148},[110,256,257],{"class":208},"\"",[110,259,260],{"class":212},"Alice",[110,262,257],{"class":208},[110,264,132],{"class":148},[110,266,158],{"class":124},[110,268,270],{"class":112,"line":269},8,[110,271,273],{"class":272},"sutJx","\u002F\u002F p.[[Prototype]] === Person.prototype\n",[53,275,277,278,281],{"id":276},"_3-__proto__-访问器","3. ",[32,279,280],{},"__proto__"," 访问器",[23,283,284,286,287,289,290,293,294,46],{},[32,285,280],{}," 是大多数 JavaScript 环境提供的非标准但广泛支持的访问器，用于读写对象的 ",[32,288,59],{},"。标准方法推荐使用 ",[32,291,292],{},"Object.getPrototypeOf()"," 和 ",[32,295,296],{},"Object.setPrototypeOf()",[101,298,300],{"className":103,"code":299,"language":105,"meta":106,"style":106},"const obj = {};\nconsole.log(obj.__proto__ === Object.prototype); \u002F\u002F true\n",[32,301,302,314],{"__ignoreMap":106},[110,303,304,306,309,311],{"class":112,"line":113},[110,305,242],{"class":116},[110,307,308],{"class":176}," obj",[110,310,152],{"class":151},[110,312,313],{"class":124}," {};\n",[110,315,316,319,321,323,326,328,330,333,336,338,340,342,345],{"class":112,"line":138},[110,317,318],{"class":148},"console",[110,320,145],{"class":124},[110,322,202],{"class":120},[110,324,325],{"class":148},"(obj",[110,327,145],{"class":124},[110,329,280],{"class":176},[110,331,332],{"class":151}," ===",[110,334,335],{"class":170}," Object",[110,337,145],{"class":124},[110,339,13],{"class":176},[110,341,132],{"class":148},[110,343,344],{"class":124},";",[110,346,347],{"class":272}," \u002F\u002F true\n",[53,349,351,352],{"id":350},"_4-objectcreateproto-propertiesobject","4. ",[32,353,354],{},"Object.create(proto, [propertiesObject])",[23,356,357,358,360],{},"创建一个新对象，并将其 ",[32,359,59],{}," 显式指定为第一个参数。",[101,362,364],{"className":103,"code":363,"language":105,"meta":106,"style":106},"const animal = {\n    eat() {\n        console.log(\"Eating\");\n    },\n};\nconst dog = Object.create(animal);\ndog.bark = function () {\n    console.log(\"Woof\");\n};\ndog.eat(); \u002F\u002F 'Eating' (来自原型)\n",[32,365,366,377,388,410,415,419,440,458,479,484],{"__ignoreMap":106},[110,367,368,370,373,375],{"class":112,"line":113},[110,369,242],{"class":116},[110,371,372],{"class":176}," animal",[110,374,152],{"class":151},[110,376,135],{"class":124},[110,378,379,383,386],{"class":112,"line":138},[110,380,382],{"class":381},"sVXei","    eat",[110,384,385],{"class":124},"()",[110,387,135],{"class":124},[110,389,390,393,395,397,399,401,404,406,408],{"class":112,"line":161},[110,391,392],{"class":148},"        console",[110,394,145],{"class":124},[110,396,202],{"class":120},[110,398,125],{"class":205},[110,400,257],{"class":208},[110,402,403],{"class":212},"Eating",[110,405,257],{"class":208},[110,407,132],{"class":205},[110,409,158],{"class":124},[110,411,412],{"class":112,"line":167},[110,413,414],{"class":124},"    },\n",[110,416,417],{"class":112,"line":194},[110,418,236],{"class":124},[110,420,421,423,426,428,430,432,435,438],{"class":112,"line":233},[110,422,242],{"class":116},[110,424,425],{"class":176}," dog",[110,427,152],{"class":151},[110,429,335],{"class":148},[110,431,145],{"class":124},[110,433,434],{"class":120},"create",[110,436,437],{"class":148},"(animal)",[110,439,158],{"class":124},[110,441,442,445,447,450,452,454,456],{"class":112,"line":239},[110,443,444],{"class":148},"dog",[110,446,145],{"class":124},[110,448,449],{"class":120},"bark",[110,451,152],{"class":151},[110,453,186],{"class":116},[110,455,189],{"class":124},[110,457,135],{"class":124},[110,459,460,462,464,466,468,470,473,475,477],{"class":112,"line":269},[110,461,197],{"class":148},[110,463,145],{"class":124},[110,465,202],{"class":120},[110,467,125],{"class":205},[110,469,257],{"class":208},[110,471,472],{"class":212},"Woof",[110,474,257],{"class":208},[110,476,132],{"class":205},[110,478,158],{"class":124},[110,480,482],{"class":112,"line":481},9,[110,483,236],{"class":124},[110,485,487,489,491,494,496,498],{"class":112,"line":486},10,[110,488,444],{"class":148},[110,490,145],{"class":124},[110,492,493],{"class":120},"eat",[110,495,385],{"class":148},[110,497,344],{"class":124},[110,499,500],{"class":272}," \u002F\u002F 'Eating' (来自原型)\n",[23,502,503,506],{},[32,504,505],{},"Object.create(null)"," 会创建一个没有原型的纯字典对象（适合存储数据，避免属性名冲突）。",[53,508,509],{"id":509},"原型链示例",[101,511,513],{"className":103,"code":512,"language":105,"meta":106,"style":106},"function Parent() {}\nParent.prototype.method = function () {};\n\nfunction Child() {}\nChild.prototype = Object.create(Parent.prototype);\nChild.prototype.constructor = Child;\n\nconst c = new Child();\n\u002F\u002F 原型链: c -> Child.prototype -> Parent.prototype -> Object.prototype -> null\n",[32,514,515,527,549,555,566,595,614,618,635],{"__ignoreMap":106},[110,516,517,519,522,524],{"class":112,"line":113},[110,518,117],{"class":116},[110,520,521],{"class":120}," Parent",[110,523,385],{"class":124},[110,525,526],{"class":124}," {}\n",[110,528,529,532,534,536,538,541,543,545,547],{"class":112,"line":138},[110,530,531],{"class":170},"Parent",[110,533,145],{"class":124},[110,535,13],{"class":176},[110,537,145],{"class":124},[110,539,540],{"class":120},"method",[110,542,152],{"class":151},[110,544,186],{"class":116},[110,546,189],{"class":124},[110,548,313],{"class":124},[110,550,551],{"class":112,"line":161},[110,552,554],{"emptyLinePlaceholder":553},true,"\n",[110,556,557,559,562,564],{"class":112,"line":167},[110,558,117],{"class":116},[110,560,561],{"class":120}," Child",[110,563,385],{"class":124},[110,565,526],{"class":124},[110,567,568,571,573,575,577,579,581,583,585,587,589,591,593],{"class":112,"line":194},[110,569,570],{"class":170},"Child",[110,572,145],{"class":124},[110,574,13],{"class":176},[110,576,152],{"class":151},[110,578,335],{"class":148},[110,580,145],{"class":124},[110,582,434],{"class":120},[110,584,125],{"class":148},[110,586,531],{"class":170},[110,588,145],{"class":124},[110,590,13],{"class":176},[110,592,132],{"class":148},[110,594,158],{"class":124},[110,596,597,599,601,603,605,608,610,612],{"class":112,"line":233},[110,598,570],{"class":170},[110,600,145],{"class":124},[110,602,13],{"class":176},[110,604,145],{"class":124},[110,606,607],{"class":176},"constructor",[110,609,152],{"class":151},[110,611,561],{"class":148},[110,613,158],{"class":124},[110,615,616],{"class":112,"line":239},[110,617,554],{"emptyLinePlaceholder":553},[110,619,620,622,625,627,629,631,633],{"class":112,"line":269},[110,621,242],{"class":116},[110,623,624],{"class":176}," c",[110,626,152],{"class":151},[110,628,250],{"class":151},[110,630,561],{"class":120},[110,632,385],{"class":148},[110,634,158],{"class":124},[110,636,637],{"class":112,"line":481},[110,638,639],{"class":272},"\u002F\u002F 原型链: c -> Child.prototype -> Parent.prototype -> Object.prototype -> null\n",[48,641,643],{"id":642},"二继承方式","二、继承方式",[53,645,647],{"id":646},"_1-原型链继承","1. 原型链继承",[23,649,650,651,653,654,657,660],{},"子构造函数的 ",[32,652,13],{}," 指向父构造函数的实例。",[655,656],"br",{},[27,658,659],{},"缺点","：所有子实例共享父实例的引用类型属性（如数组）；无法向父构造函数传参。",[101,662,664],{"className":103,"code":663,"language":105,"meta":106,"style":106},"function Parent() {\n    this.colors = [\"red\"];\n}\nfunction Child() {}\nChild.prototype = new Parent();\nconst c1 = new Child();\nc1.colors.push(\"blue\"); \u002F\u002F 影响所有实例\n",[32,665,666,676,702,706,716,734,751],{"__ignoreMap":106},[110,667,668,670,672,674],{"class":112,"line":113},[110,669,117],{"class":116},[110,671,521],{"class":120},[110,673,385],{"class":124},[110,675,135],{"class":124},[110,677,678,680,682,685,687,690,692,695,697,700],{"class":112,"line":138},[110,679,142],{"class":141},[110,681,145],{"class":124},[110,683,684],{"class":148},"colors",[110,686,152],{"class":151},[110,688,689],{"class":205}," [",[110,691,257],{"class":208},[110,693,694],{"class":212},"red",[110,696,257],{"class":208},[110,698,699],{"class":205},"]",[110,701,158],{"class":124},[110,703,704],{"class":112,"line":161},[110,705,164],{"class":124},[110,707,708,710,712,714],{"class":112,"line":167},[110,709,117],{"class":116},[110,711,561],{"class":120},[110,713,385],{"class":124},[110,715,526],{"class":124},[110,717,718,720,722,724,726,728,730,732],{"class":112,"line":194},[110,719,570],{"class":170},[110,721,145],{"class":124},[110,723,13],{"class":176},[110,725,152],{"class":151},[110,727,250],{"class":151},[110,729,521],{"class":120},[110,731,385],{"class":148},[110,733,158],{"class":124},[110,735,736,738,741,743,745,747,749],{"class":112,"line":233},[110,737,242],{"class":116},[110,739,740],{"class":176}," c1",[110,742,152],{"class":151},[110,744,250],{"class":151},[110,746,561],{"class":120},[110,748,385],{"class":148},[110,750,158],{"class":124},[110,752,753,756,758,760,762,765,767,769,772,774,776,778],{"class":112,"line":239},[110,754,755],{"class":148},"c1",[110,757,145],{"class":124},[110,759,684],{"class":148},[110,761,145],{"class":124},[110,763,764],{"class":120},"push",[110,766,125],{"class":148},[110,768,257],{"class":208},[110,770,771],{"class":212},"blue",[110,773,257],{"class":208},[110,775,132],{"class":148},[110,777,344],{"class":124},[110,779,780],{"class":272}," \u002F\u002F 影响所有实例\n",[53,782,784],{"id":783},"_2-构造函数盗用经典盗用-callapply","2. 构造函数盗用（经典盗用 \u002F call\u002Fapply）",[23,786,787,788,46,790,792,794],{},"在子构造函数内部调用父构造函数，并绑定 ",[32,789,219],{},[655,791],{},[27,793,659],{},"：不能复用父原型上的方法，每个实例都会创建一份方法副本。",[101,796,798],{"className":103,"code":797,"language":105,"meta":106,"style":106},"function Parent(name) {\n    this.name = name;\n}\nfunction Child(name, age) {\n    Parent.call(this, name);\n    this.age = age;\n}\n",[32,799,800,814,828,832,852,874,889],{"__ignoreMap":106},[110,801,802,804,806,808,810,812],{"class":112,"line":113},[110,803,117],{"class":116},[110,805,521],{"class":120},[110,807,125],{"class":124},[110,809,129],{"class":128},[110,811,132],{"class":124},[110,813,135],{"class":124},[110,815,816,818,820,822,824,826],{"class":112,"line":138},[110,817,142],{"class":141},[110,819,145],{"class":124},[110,821,129],{"class":148},[110,823,152],{"class":151},[110,825,155],{"class":148},[110,827,158],{"class":124},[110,829,830],{"class":112,"line":161},[110,831,164],{"class":124},[110,833,834,836,838,840,842,845,848,850],{"class":112,"line":167},[110,835,117],{"class":116},[110,837,561],{"class":120},[110,839,125],{"class":124},[110,841,129],{"class":128},[110,843,844],{"class":124},",",[110,846,847],{"class":128}," age",[110,849,132],{"class":124},[110,851,135],{"class":124},[110,853,854,857,859,862,864,866,868,870,872],{"class":112,"line":194},[110,855,856],{"class":148},"    Parent",[110,858,145],{"class":124},[110,860,861],{"class":120},"call",[110,863,125],{"class":205},[110,865,219],{"class":141},[110,867,844],{"class":124},[110,869,155],{"class":148},[110,871,132],{"class":205},[110,873,158],{"class":124},[110,875,876,878,880,883,885,887],{"class":112,"line":233},[110,877,142],{"class":141},[110,879,145],{"class":124},[110,881,882],{"class":148},"age",[110,884,152],{"class":151},[110,886,847],{"class":148},[110,888,158],{"class":124},[110,890,891],{"class":112,"line":239},[110,892,164],{"class":124},[53,894,896],{"id":895},"_3-组合继承原型链-构造函数盗用","3. 组合继承（原型链 + 构造函数盗用）",[23,898,899,902,903,906,907,909,910,912,914],{},[27,900,901],{},"优点","：父构造函数执行两次（一次用于 ",[32,904,905],{},"Child.prototype = new Parent()","，一次在 ",[32,908,570],{}," 内部调用），但解决了传参与属性共享问题。",[655,911],{},[27,913,659],{},"：效率稍低（父实例的无关属性存在于原型上）。",[101,916,918],{"className":103,"code":917,"language":105,"meta":106,"style":106},"function Parent(name) {\n    this.name = name;\n}\nParent.prototype.say = function () {};\nfunction Child(name, age) {\n    Parent.call(this, name);\n    this.age = age;\n}\nChild.prototype = new Parent();\nChild.prototype.constructor = Child;\n",[32,919,920,934,948,952,973,991,1011,1025,1029,1047],{"__ignoreMap":106},[110,921,922,924,926,928,930,932],{"class":112,"line":113},[110,923,117],{"class":116},[110,925,521],{"class":120},[110,927,125],{"class":124},[110,929,129],{"class":128},[110,931,132],{"class":124},[110,933,135],{"class":124},[110,935,936,938,940,942,944,946],{"class":112,"line":138},[110,937,142],{"class":141},[110,939,145],{"class":124},[110,941,129],{"class":148},[110,943,152],{"class":151},[110,945,155],{"class":148},[110,947,158],{"class":124},[110,949,950],{"class":112,"line":161},[110,951,164],{"class":124},[110,953,954,956,958,960,962,965,967,969,971],{"class":112,"line":167},[110,955,531],{"class":170},[110,957,145],{"class":124},[110,959,13],{"class":176},[110,961,145],{"class":124},[110,963,964],{"class":120},"say",[110,966,152],{"class":151},[110,968,186],{"class":116},[110,970,189],{"class":124},[110,972,313],{"class":124},[110,974,975,977,979,981,983,985,987,989],{"class":112,"line":194},[110,976,117],{"class":116},[110,978,561],{"class":120},[110,980,125],{"class":124},[110,982,129],{"class":128},[110,984,844],{"class":124},[110,986,847],{"class":128},[110,988,132],{"class":124},[110,990,135],{"class":124},[110,992,993,995,997,999,1001,1003,1005,1007,1009],{"class":112,"line":233},[110,994,856],{"class":148},[110,996,145],{"class":124},[110,998,861],{"class":120},[110,1000,125],{"class":205},[110,1002,219],{"class":141},[110,1004,844],{"class":124},[110,1006,155],{"class":148},[110,1008,132],{"class":205},[110,1010,158],{"class":124},[110,1012,1013,1015,1017,1019,1021,1023],{"class":112,"line":239},[110,1014,142],{"class":141},[110,1016,145],{"class":124},[110,1018,882],{"class":148},[110,1020,152],{"class":151},[110,1022,847],{"class":148},[110,1024,158],{"class":124},[110,1026,1027],{"class":112,"line":269},[110,1028,164],{"class":124},[110,1030,1031,1033,1035,1037,1039,1041,1043,1045],{"class":112,"line":481},[110,1032,570],{"class":170},[110,1034,145],{"class":124},[110,1036,13],{"class":176},[110,1038,152],{"class":151},[110,1040,250],{"class":151},[110,1042,521],{"class":120},[110,1044,385],{"class":148},[110,1046,158],{"class":124},[110,1048,1049,1051,1053,1055,1057,1059,1061,1063],{"class":112,"line":486},[110,1050,570],{"class":170},[110,1052,145],{"class":124},[110,1054,13],{"class":176},[110,1056,145],{"class":124},[110,1058,607],{"class":176},[110,1060,152],{"class":151},[110,1062,561],{"class":148},[110,1064,158],{"class":124},[53,1066,1068],{"id":1067},"_4-寄生组合继承最优","4. 寄生组合继承（最优）",[23,1070,1071,1072,1075],{},"避免调用两次父构造函数，使用 ",[32,1073,1074],{},"Object.create"," 创建父原型的副本，然后增强该对象。",[101,1077,1079],{"className":103,"code":1078,"language":105,"meta":106,"style":106},"function inheritPrototype(child, parent) {\n    const prototype = Object.create(parent.prototype);\n    prototype.constructor = child;\n    child.prototype = prototype;\n}\nfunction Parent(name) {\n    this.name = name;\n}\nfunction Child(name, age) {\n    Parent.call(this, name);\n    this.age = age;\n}\ninheritPrototype(Child, Parent);\n",[32,1080,1081,1102,1131,1147,1162,1166,1180,1194,1198,1216,1236,1251,1256],{"__ignoreMap":106},[110,1082,1083,1085,1088,1090,1093,1095,1098,1100],{"class":112,"line":113},[110,1084,117],{"class":116},[110,1086,1087],{"class":120}," inheritPrototype",[110,1089,125],{"class":124},[110,1091,1092],{"class":128},"child",[110,1094,844],{"class":124},[110,1096,1097],{"class":128}," parent",[110,1099,132],{"class":124},[110,1101,135],{"class":124},[110,1103,1104,1107,1110,1112,1114,1116,1118,1120,1123,1125,1127,1129],{"class":112,"line":138},[110,1105,1106],{"class":116},"    const",[110,1108,1109],{"class":176}," prototype",[110,1111,152],{"class":151},[110,1113,335],{"class":148},[110,1115,145],{"class":124},[110,1117,434],{"class":120},[110,1119,125],{"class":205},[110,1121,1122],{"class":170},"parent",[110,1124,145],{"class":124},[110,1126,13],{"class":176},[110,1128,132],{"class":205},[110,1130,158],{"class":124},[110,1132,1133,1136,1138,1140,1142,1145],{"class":112,"line":161},[110,1134,1135],{"class":148},"    prototype",[110,1137,145],{"class":124},[110,1139,607],{"class":176},[110,1141,152],{"class":151},[110,1143,1144],{"class":148}," child",[110,1146,158],{"class":124},[110,1148,1149,1152,1154,1156,1158,1160],{"class":112,"line":167},[110,1150,1151],{"class":170},"    child",[110,1153,145],{"class":124},[110,1155,13],{"class":176},[110,1157,152],{"class":151},[110,1159,1109],{"class":148},[110,1161,158],{"class":124},[110,1163,1164],{"class":112,"line":194},[110,1165,164],{"class":124},[110,1167,1168,1170,1172,1174,1176,1178],{"class":112,"line":233},[110,1169,117],{"class":116},[110,1171,521],{"class":120},[110,1173,125],{"class":124},[110,1175,129],{"class":128},[110,1177,132],{"class":124},[110,1179,135],{"class":124},[110,1181,1182,1184,1186,1188,1190,1192],{"class":112,"line":239},[110,1183,142],{"class":141},[110,1185,145],{"class":124},[110,1187,129],{"class":148},[110,1189,152],{"class":151},[110,1191,155],{"class":148},[110,1193,158],{"class":124},[110,1195,1196],{"class":112,"line":269},[110,1197,164],{"class":124},[110,1199,1200,1202,1204,1206,1208,1210,1212,1214],{"class":112,"line":481},[110,1201,117],{"class":116},[110,1203,561],{"class":120},[110,1205,125],{"class":124},[110,1207,129],{"class":128},[110,1209,844],{"class":124},[110,1211,847],{"class":128},[110,1213,132],{"class":124},[110,1215,135],{"class":124},[110,1217,1218,1220,1222,1224,1226,1228,1230,1232,1234],{"class":112,"line":486},[110,1219,856],{"class":148},[110,1221,145],{"class":124},[110,1223,861],{"class":120},[110,1225,125],{"class":205},[110,1227,219],{"class":141},[110,1229,844],{"class":124},[110,1231,155],{"class":148},[110,1233,132],{"class":205},[110,1235,158],{"class":124},[110,1237,1239,1241,1243,1245,1247,1249],{"class":112,"line":1238},11,[110,1240,142],{"class":141},[110,1242,145],{"class":124},[110,1244,882],{"class":148},[110,1246,152],{"class":151},[110,1248,847],{"class":148},[110,1250,158],{"class":124},[110,1252,1254],{"class":112,"line":1253},12,[110,1255,164],{"class":124},[110,1257,1259,1262,1265,1267,1270],{"class":112,"line":1258},13,[110,1260,1261],{"class":120},"inheritPrototype",[110,1263,1264],{"class":148},"(Child",[110,1266,844],{"class":124},[110,1268,1269],{"class":148}," Parent)",[110,1271,158],{"class":124},[23,1273,1274,1276],{},[27,1275,901],{},"：只调用一次父构造函数，原型链干净，是 ES5 环境下最理想的继承模式。",[53,1278,1280,1281,1283],{"id":1279},"_5-es6-class-的本质语法糖","5. ES6 ",[32,1282,34],{}," 的本质（语法糖）",[23,1285,1286,1287,293,1289,1292],{},"ES6 的 ",[32,1288,34],{},[32,1290,1291],{},"extends"," 底层仍是基于原型链的寄生组合继承。",[101,1294,1296],{"className":103,"code":1295,"language":105,"meta":106,"style":106},"class Parent {\n    constructor(name) {\n        this.name = name;\n    }\n}\nclass Child extends Parent {\n    constructor(name, age) {\n        super(name);\n        this.age = age;\n    }\n}\n",[32,1297,1298,1307,1320,1335,1340,1344,1357,1373,1386,1400,1404],{"__ignoreMap":106},[110,1299,1300,1302,1305],{"class":112,"line":113},[110,1301,34],{"class":116},[110,1303,521],{"class":1304},"sbgvK",[110,1306,135],{"class":124},[110,1308,1309,1312,1314,1316,1318],{"class":112,"line":138},[110,1310,1311],{"class":116},"    constructor",[110,1313,125],{"class":124},[110,1315,129],{"class":128},[110,1317,132],{"class":124},[110,1319,135],{"class":124},[110,1321,1322,1325,1327,1329,1331,1333],{"class":112,"line":161},[110,1323,1324],{"class":141},"        this",[110,1326,145],{"class":124},[110,1328,129],{"class":148},[110,1330,152],{"class":151},[110,1332,155],{"class":148},[110,1334,158],{"class":124},[110,1336,1337],{"class":112,"line":167},[110,1338,1339],{"class":124},"    }\n",[110,1341,1342],{"class":112,"line":194},[110,1343,164],{"class":124},[110,1345,1346,1348,1350,1353,1355],{"class":112,"line":233},[110,1347,34],{"class":116},[110,1349,561],{"class":1304},[110,1351,1352],{"class":116}," extends",[110,1354,521],{"class":1304},[110,1356,135],{"class":124},[110,1358,1359,1361,1363,1365,1367,1369,1371],{"class":112,"line":239},[110,1360,1311],{"class":116},[110,1362,125],{"class":124},[110,1364,129],{"class":128},[110,1366,844],{"class":124},[110,1368,847],{"class":128},[110,1370,132],{"class":124},[110,1372,135],{"class":124},[110,1374,1375,1378,1380,1382,1384],{"class":112,"line":269},[110,1376,1377],{"class":176},"        super",[110,1379,125],{"class":205},[110,1381,129],{"class":148},[110,1383,132],{"class":205},[110,1385,158],{"class":124},[110,1387,1388,1390,1392,1394,1396,1398],{"class":112,"line":481},[110,1389,1324],{"class":141},[110,1391,145],{"class":124},[110,1393,882],{"class":148},[110,1395,152],{"class":151},[110,1397,847],{"class":148},[110,1399,158],{"class":124},[110,1401,1402],{"class":112,"line":486},[110,1403,1339],{"class":124},[110,1405,1406],{"class":112,"line":1238},[110,1407,164],{"class":124},[23,1409,1410,1412],{},[32,1411,34],{}," 内部实现了：",[1414,1415,1416,1423,1433,1436],"ul",{},[1417,1418,1419,1420,1422],"li",{},"构造函数的 ",[32,1421,13],{}," 关联",[1417,1424,1425,1426,1429,1430],{},"自动调用 ",[32,1427,1428],{},"super()"," 即 ",[32,1431,1432],{},"Parent.call(this)",[1417,1434,1435],{},"静态方法挂载在类本身上",[1417,1437,1438,1441,1442,1444,1445,1448,1449,1452],{},[27,1439,1440],{},"class 方法","定义在 ",[32,1443,13],{}," 上且默认",[27,1446,1447],{},"不可枚举","（与手写 ",[32,1450,1451],{},"Person.prototype.say = function(){}"," 默认可枚举不同）",[48,1454,1456],{"id":1455},"三类的进阶特性","三、类的进阶特性",[53,1458,1460],{"id":1459},"_1-静态方法static","1. 静态方法（static）",[23,1462,1463,1464,1467],{},"使用 ",[32,1465,1466],{},"static"," 关键字定义的方法属于类本身，而非实例。它们通常用于工具函数。",[101,1469,1471],{"className":103,"code":1470,"language":105,"meta":106,"style":106},"class MathUtils {\n    static add(a, b) {\n        return a + b;\n    }\n}\nconsole.log(MathUtils.add(2, 3)); \u002F\u002F 5\n\u002F\u002F 实例无法访问静态方法: new MathUtils().add -> TypeError\n",[32,1472,1473,1482,1503,1519,1523,1527,1562],{"__ignoreMap":106},[110,1474,1475,1477,1480],{"class":112,"line":113},[110,1476,34],{"class":116},[110,1478,1479],{"class":1304}," MathUtils",[110,1481,135],{"class":124},[110,1483,1484,1487,1490,1492,1494,1496,1499,1501],{"class":112,"line":138},[110,1485,1486],{"class":116},"    static",[110,1488,1489],{"class":381}," add",[110,1491,125],{"class":124},[110,1493,37],{"class":128},[110,1495,844],{"class":124},[110,1497,1498],{"class":128}," b",[110,1500,132],{"class":124},[110,1502,135],{"class":124},[110,1504,1505,1509,1512,1515,1517],{"class":112,"line":161},[110,1506,1508],{"class":1507},"sVHd0","        return",[110,1510,1511],{"class":148}," a",[110,1513,1514],{"class":151}," +",[110,1516,1498],{"class":148},[110,1518,158],{"class":124},[110,1520,1521],{"class":112,"line":167},[110,1522,1339],{"class":124},[110,1524,1525],{"class":112,"line":194},[110,1526,164],{"class":124},[110,1528,1529,1531,1533,1535,1538,1540,1543,1545,1549,1551,1554,1557,1559],{"class":112,"line":233},[110,1530,318],{"class":148},[110,1532,145],{"class":124},[110,1534,202],{"class":120},[110,1536,1537],{"class":148},"(MathUtils",[110,1539,145],{"class":124},[110,1541,1542],{"class":120},"add",[110,1544,125],{"class":148},[110,1546,1548],{"class":1547},"srdBf","2",[110,1550,844],{"class":124},[110,1552,1553],{"class":1547}," 3",[110,1555,1556],{"class":148},"))",[110,1558,344],{"class":124},[110,1560,1561],{"class":272}," \u002F\u002F 5\n",[110,1563,1564],{"class":112,"line":239},[110,1565,1566],{"class":272},"\u002F\u002F 实例无法访问静态方法: new MathUtils().add -> TypeError\n",[23,1568,1569,1570,1572,1573,1575],{},"静态方法内部 ",[32,1571,219],{}," 指向类（而非实例），也可以被 ",[32,1574,1291],{}," 子类继承。",[53,1577,1579,1580,1583],{"id":1578},"_2-私有字段","2. 私有字段（",[32,1581,1582],{},"#","）",[23,1585,1586],{},"ES2022 正式引入私有字段，只能在类内部访问，真正实现封装。",[101,1588,1590],{"className":103,"code":1589,"language":105,"meta":106,"style":106},"class Person {\n    #age;\n    constructor(name, age) {\n        this.name = name;\n        this.#age = age;\n    }\n    #privateMethod() {\n        return this.#age;\n    }\n    getAge() {\n        return this.#privateMethod();\n    }\n}\nconst p = new Person(\"Bob\", 30);\nconsole.log(p.name); \u002F\u002F 'Bob'\nconsole.log(p.#age); \u002F\u002F SyntaxError\nconsole.log(p.getAge()); \u002F\u002F 30\n",[32,1591,1592,1600,1608,1624,1638,1653,1657,1669,1682,1686,1695,1710,1714,1718,1749,1771,1792],{"__ignoreMap":106},[110,1593,1594,1596,1598],{"class":112,"line":113},[110,1595,34],{"class":116},[110,1597,121],{"class":1304},[110,1599,135],{"class":124},[110,1601,1602,1606],{"class":112,"line":138},[110,1603,1605],{"class":1604},"sucvu","    #age",[110,1607,158],{"class":124},[110,1609,1610,1612,1614,1616,1618,1620,1622],{"class":112,"line":161},[110,1611,1311],{"class":116},[110,1613,125],{"class":124},[110,1615,129],{"class":128},[110,1617,844],{"class":124},[110,1619,847],{"class":128},[110,1621,132],{"class":124},[110,1623,135],{"class":124},[110,1625,1626,1628,1630,1632,1634,1636],{"class":112,"line":167},[110,1627,1324],{"class":141},[110,1629,145],{"class":124},[110,1631,129],{"class":148},[110,1633,152],{"class":151},[110,1635,155],{"class":148},[110,1637,158],{"class":124},[110,1639,1640,1642,1644,1647,1649,1651],{"class":112,"line":194},[110,1641,1324],{"class":141},[110,1643,145],{"class":124},[110,1645,1646],{"class":148},"#age",[110,1648,152],{"class":151},[110,1650,847],{"class":148},[110,1652,158],{"class":124},[110,1654,1655],{"class":112,"line":233},[110,1656,1339],{"class":124},[110,1658,1659,1662,1665,1667],{"class":112,"line":239},[110,1660,1661],{"class":148},"    #",[110,1663,1664],{"class":381},"privateMethod",[110,1666,385],{"class":124},[110,1668,135],{"class":124},[110,1670,1671,1673,1676,1678,1680],{"class":112,"line":269},[110,1672,1508],{"class":1507},[110,1674,1675],{"class":141}," this",[110,1677,145],{"class":124},[110,1679,1646],{"class":148},[110,1681,158],{"class":124},[110,1683,1684],{"class":112,"line":481},[110,1685,1339],{"class":124},[110,1687,1688,1691,1693],{"class":112,"line":486},[110,1689,1690],{"class":381},"    getAge",[110,1692,385],{"class":124},[110,1694,135],{"class":124},[110,1696,1697,1699,1701,1703,1706,1708],{"class":112,"line":1238},[110,1698,1508],{"class":1507},[110,1700,1675],{"class":141},[110,1702,145],{"class":124},[110,1704,1705],{"class":120},"#privateMethod",[110,1707,385],{"class":205},[110,1709,158],{"class":124},[110,1711,1712],{"class":112,"line":1253},[110,1713,1339],{"class":124},[110,1715,1716],{"class":112,"line":1258},[110,1717,164],{"class":124},[110,1719,1721,1723,1725,1727,1729,1731,1733,1735,1738,1740,1742,1745,1747],{"class":112,"line":1720},14,[110,1722,242],{"class":116},[110,1724,245],{"class":176},[110,1726,152],{"class":151},[110,1728,250],{"class":151},[110,1730,121],{"class":120},[110,1732,125],{"class":148},[110,1734,257],{"class":208},[110,1736,1737],{"class":212},"Bob",[110,1739,257],{"class":208},[110,1741,844],{"class":124},[110,1743,1744],{"class":1547}," 30",[110,1746,132],{"class":148},[110,1748,158],{"class":124},[110,1750,1752,1754,1756,1758,1761,1763,1766,1768],{"class":112,"line":1751},15,[110,1753,318],{"class":148},[110,1755,145],{"class":124},[110,1757,202],{"class":120},[110,1759,1760],{"class":148},"(p",[110,1762,145],{"class":124},[110,1764,1765],{"class":148},"name)",[110,1767,344],{"class":124},[110,1769,1770],{"class":272}," \u002F\u002F 'Bob'\n",[110,1772,1774,1776,1778,1780,1782,1784,1787,1789],{"class":112,"line":1773},16,[110,1775,318],{"class":148},[110,1777,145],{"class":124},[110,1779,202],{"class":120},[110,1781,1760],{"class":148},[110,1783,145],{"class":124},[110,1785,1786],{"class":148},"#age)",[110,1788,344],{"class":124},[110,1790,1791],{"class":272}," \u002F\u002F SyntaxError\n",[110,1793,1795,1797,1799,1801,1803,1805,1808,1811,1813],{"class":112,"line":1794},17,[110,1796,318],{"class":148},[110,1798,145],{"class":124},[110,1800,202],{"class":120},[110,1802,1760],{"class":148},[110,1804,145],{"class":124},[110,1806,1807],{"class":120},"getAge",[110,1809,1810],{"class":148},"())",[110,1812,344],{"class":124},[110,1814,1815],{"class":272}," \u002F\u002F 30\n",[23,1817,1818,1819,1822],{},"私有字段在编译时静态绑定，不会因为 ",[32,1820,1821],{},"Object.getOwnPropertyNames"," 等操作暴露。",[53,1824,277,1826,1829,1830],{"id":1825},"_3-instanceof-与-symbolhasinstance",[32,1827,1828],{},"instanceof"," 与 ",[32,1831,1832],{},"Symbol.hasInstance",[23,1834,1835,1837,1838,1840],{},[32,1836,1828],{}," 运算符检查对象的原型链中是否包含构造函数的 ",[32,1839,13],{}," 属性。",[101,1842,1844],{"className":103,"code":1843,"language":105,"meta":106,"style":106},"[] instanceof Array; \u002F\u002F true\n[] instanceof Object; \u002F\u002F true (因为 Array.prototype 继承自 Object.prototype)\n",[32,1845,1846,1860],{"__ignoreMap":106},[110,1847,1848,1851,1853,1856,1858],{"class":112,"line":113},[110,1849,1850],{"class":148},"[] ",[110,1852,1828],{"class":151},[110,1854,1855],{"class":1304}," Array",[110,1857,344],{"class":124},[110,1859,347],{"class":272},[110,1861,1862,1864,1866,1868,1870],{"class":112,"line":138},[110,1863,1850],{"class":148},[110,1865,1828],{"class":151},[110,1867,335],{"class":1304},[110,1869,344],{"class":124},[110,1871,1872],{"class":272}," \u002F\u002F true (因为 Array.prototype 继承自 Object.prototype)\n",[23,1874,1875,1876,1878,1879,1881],{},"可以通过 ",[32,1877,1832],{}," 自定义 ",[32,1880,1828],{}," 行为：",[101,1883,1885],{"className":103,"code":1884,"language":105,"meta":106,"style":106},"class MyArray {\n    static [Symbol.hasInstance](instance) {\n        return Array.isArray(instance);\n    }\n}\nconsole.log([] instanceof MyArray); \u002F\u002F true\n",[32,1886,1887,1896,1917,1936,1940,1944],{"__ignoreMap":106},[110,1888,1889,1891,1894],{"class":112,"line":113},[110,1890,34],{"class":116},[110,1892,1893],{"class":1304}," MyArray",[110,1895,135],{"class":124},[110,1897,1898,1900,1903,1905,1908,1910,1913,1915],{"class":112,"line":138},[110,1899,1486],{"class":116},[110,1901,1902],{"class":148}," [Symbol",[110,1904,145],{"class":124},[110,1906,1907],{"class":148},"hasInstance]",[110,1909,125],{"class":124},[110,1911,1912],{"class":128},"instance",[110,1914,132],{"class":124},[110,1916,135],{"class":124},[110,1918,1919,1921,1923,1925,1928,1930,1932,1934],{"class":112,"line":161},[110,1920,1508],{"class":1507},[110,1922,1855],{"class":148},[110,1924,145],{"class":124},[110,1926,1927],{"class":120},"isArray",[110,1929,125],{"class":205},[110,1931,1912],{"class":148},[110,1933,132],{"class":205},[110,1935,158],{"class":124},[110,1937,1938],{"class":112,"line":167},[110,1939,1339],{"class":124},[110,1941,1942],{"class":112,"line":194},[110,1943,164],{"class":124},[110,1945,1946,1948,1950,1952,1955,1957,1959,1961,1963],{"class":112,"line":233},[110,1947,318],{"class":148},[110,1949,145],{"class":124},[110,1951,202],{"class":120},[110,1953,1954],{"class":148},"([] ",[110,1956,1828],{"class":151},[110,1958,1893],{"class":1304},[110,1960,132],{"class":148},[110,1962,344],{"class":124},[110,1964,347],{"class":272},[48,1966,1968,1969,1971],{"id":1967},"四new-操作符内部步骤","四、",[32,1970,92],{}," 操作符内部步骤",[23,1973,1463,1974,1976],{},[32,1975,92],{}," 调用一个构造函数时，引擎会执行以下 4 个步骤：",[1978,1979,1980,1989,2008,2027],"ol",{},[1417,1981,1982,1985,1986],{},[27,1983,1984],{},"创建一个新的空对象","：",[32,1987,1988],{},"const obj = {};",[1417,1990,1991,1994,1995,1997,1998,2000,2001,2004,2005,1583],{},[27,1992,1993],{},"设置原型","：将新对象的 ",[32,1996,59],{}," 指向构造函数的 ",[32,1999,13],{}," 属性：",[32,2002,2003],{},"obj.__proto__ = Constructor.prototype;","（内部操作是 ",[32,2006,2007],{},"Object.setPrototypeOf(obj, Constructor.prototype)",[1417,2009,2010,2016,2017,2020,2021,2023,2024],{},[27,2011,2012,2013,2015],{},"绑定 ",[32,2014,219],{}," 并执行构造函数","：调用 ",[32,2018,2019],{},"Constructor"," 并将 ",[32,2022,219],{}," 绑定到新对象上，传递参数：",[32,2025,2026],{},"const result = Constructor.apply(obj, args);",[1417,2028,2029,2032,2033],{},[27,2030,2031],{},"返回对象","：\n",[1414,2034,2035,2041],{},[1417,2036,2037,2038,2040],{},"如果构造函数返回一个对象（非 ",[32,2039,69],{},"），则返回该对象；",[1417,2042,2043,2044,46],{},"否则返回第 1 步创建的新对象 ",[32,2045,2046],{},"obj",[101,2048,2050],{"className":103,"code":2049,"language":105,"meta":106,"style":106},"function Person(name) {\n    this.name = name;\n    return { custom: true }; \u002F\u002F 如果返回对象，new 的结果就是这个对象\n}\nconst p = new Person(\"Alice\");\nconsole.log(p); \u002F\u002F { custom: true }，不是 Person 实例\n",[32,2051,2052,2066,2080,2104,2108,2132],{"__ignoreMap":106},[110,2053,2054,2056,2058,2060,2062,2064],{"class":112,"line":113},[110,2055,117],{"class":116},[110,2057,121],{"class":120},[110,2059,125],{"class":124},[110,2061,129],{"class":128},[110,2063,132],{"class":124},[110,2065,135],{"class":124},[110,2067,2068,2070,2072,2074,2076,2078],{"class":112,"line":138},[110,2069,142],{"class":141},[110,2071,145],{"class":124},[110,2073,129],{"class":148},[110,2075,152],{"class":151},[110,2077,155],{"class":148},[110,2079,158],{"class":124},[110,2081,2082,2085,2088,2091,2094,2098,2101],{"class":112,"line":161},[110,2083,2084],{"class":1507},"    return",[110,2086,2087],{"class":124}," {",[110,2089,2090],{"class":205}," custom",[110,2092,2093],{"class":124},":",[110,2095,2097],{"class":2096},"syTEX"," true",[110,2099,2100],{"class":124}," };",[110,2102,2103],{"class":272}," \u002F\u002F 如果返回对象，new 的结果就是这个对象\n",[110,2105,2106],{"class":112,"line":167},[110,2107,164],{"class":124},[110,2109,2110,2112,2114,2116,2118,2120,2122,2124,2126,2128,2130],{"class":112,"line":194},[110,2111,242],{"class":116},[110,2113,245],{"class":176},[110,2115,152],{"class":151},[110,2117,250],{"class":151},[110,2119,121],{"class":120},[110,2121,125],{"class":148},[110,2123,257],{"class":208},[110,2125,260],{"class":212},[110,2127,257],{"class":208},[110,2129,132],{"class":148},[110,2131,158],{"class":124},[110,2133,2134,2136,2138,2140,2143,2145],{"class":112,"line":233},[110,2135,318],{"class":148},[110,2137,145],{"class":124},[110,2139,202],{"class":120},[110,2141,2142],{"class":148},"(p)",[110,2144,344],{"class":124},[110,2146,2147],{"class":272}," \u002F\u002F { custom: true }，不是 Person 实例\n",[23,2149,2150,2151,2153],{},"正常情况下，构造函数应避免显式返回对象，以确保 ",[32,2152,92],{}," 行为符合预期。",[48,2155,2156],{"id":2156},"总结",[1414,2158,2159,2167,2173,2176],{},[1417,2160,2161,2163,2164,2166],{},[27,2162,29],{},"是 JavaScript 实现继承的底层机制，通过 ",[32,2165,59],{}," 串联对象。",[1417,2168,2169,2170,2172],{},"各种继承模式从混乱到优雅，最终 ES6 ",[32,2171,34],{}," 提供了清晰的语法，其本质仍然是原型链。",[1417,2174,2175],{},"现代 JavaScript 支持静态方法、私有字段等，进一步增强了类的封装性和表达能力。",[1417,2177,2178,2179,2181],{},"理解 ",[32,2180,92],{}," 的执行步骤有助于掌握构造函数和对象创建的过程。",[23,2183,2184],{},"掌握这些内容，就能深入理解 JavaScript 的对象系统，写出更健壮、优雅的代码。",[48,2186,2187],{"id":2187},"参考文献",[23,2189,2190],{},"以下链接在编写时均可正常访问：",[2192,2193,2194,2207],"table",{},[2195,2196,2197],"thead",{},[2198,2199,2200,2204],"tr",{},[2201,2202,2203],"th",{},"资料",[2201,2205,2206],{},"说明",[2208,2209,2210,2223,2235,2249,2261],"tbody",{},[2198,2211,2212,2221],{},[2213,2214,2215],"td",{},[37,2216,2220],{"href":2217,"rel":2218},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FInheritance_and_the_prototype_chain",[2219],"nofollow","MDN：继承与原型链",[2213,2222,29],{},[2198,2224,2225,2232],{},[2213,2226,2227],{},[37,2228,2231],{"href":2229,"rel":2230},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses",[2219],"MDN：class",[2213,2233,2234],{},"ES6 类语法",[2198,2236,2237,2244],{},[2213,2238,2239],{},[37,2240,2243],{"href":2241,"rel":2242},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fnew",[2219],"MDN：new",[2213,2245,2246,2248],{},[32,2247,92],{}," 运算符",[2198,2250,2251,2258],{},[2213,2252,2253],{},[37,2254,2257],{"href":2255,"rel":2256},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Finstanceof",[2219],"MDN：instanceof",[2213,2259,2260],{},"类型检测",[2198,2262,2263,2270],{},[2213,2264,2265],{},[37,2266,2269],{"href":2267,"rel":2268},"https:\u002F\u002Ftc39.es\u002Fecma262\u002F#sec-objects",[2219],"ECMA-262：对象",[2213,2271,2272],{},"规范（英文）",[2274,2275,2276],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":106,"searchDepth":138,"depth":138,"links":2278},[2279,2290,2298,2305,2307,2308],{"id":50,"depth":138,"text":51,"children":2280},[2281,2283,2285,2287,2289],{"id":55,"depth":161,"text":2282},"1. [[Prototype]] 内部槽位",{"id":79,"depth":161,"text":2284},"2. prototype 属性",{"id":276,"depth":161,"text":2286},"3. __proto__ 访问器",{"id":350,"depth":161,"text":2288},"4. Object.create(proto, [propertiesObject])",{"id":509,"depth":161,"text":509},{"id":642,"depth":138,"text":643,"children":2291},[2292,2293,2294,2295,2296],{"id":646,"depth":161,"text":647},{"id":783,"depth":161,"text":784},{"id":895,"depth":161,"text":896},{"id":1067,"depth":161,"text":1068},{"id":1279,"depth":161,"text":2297},"5. ES6 class 的本质（语法糖）",{"id":1455,"depth":138,"text":1456,"children":2299},[2300,2301,2303],{"id":1459,"depth":161,"text":1460},{"id":1578,"depth":161,"text":2302},"2. 私有字段（#）",{"id":1825,"depth":161,"text":2304},"3. instanceof 与 Symbol.hasInstance",{"id":1967,"depth":138,"text":2306},"四、new 操作符内部步骤",{"id":2156,"depth":138,"text":2156},{"id":2187,"depth":138,"text":2187},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fprototype","knowledge\u002Fknowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fprototype.md","md",{"items":2314},[2315,2319,2323,2327,2331,2335],{"path":2316,"title":2317,"description":2318,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Ferror","错误处理与调试","结构化错误类型、try\u002Fcatch 与全局未捕获处理是健壮应用的基础。",{"path":2320,"title":2321,"description":2322,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom","浏览器相关 API","DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 标签。",{"path":2324,"title":2325,"description":2326,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance","性能优化","防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。",{"path":2328,"title":2329,"description":2330,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon","模块化与工程化","ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 JavaScript 基础 · 模块。",{"path":2332,"title":2333,"description":2334,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope","执行模型与作用域","执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 var \u002F let \u002F const 的差异。语言概览见 JavaScript 基础。",{"path":2336,"title":2337,"description":2338,"category":10,"score":233},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fmap-set","数据结构与集合增强","Map \u002F Set、WeakMap \u002F WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。",{"series":2340,"title":105,"items":2341,"index":486,"prev":2380,"next":2381},"booklet\u002Fweb\u002Fjs",[2342,2344,2347,2349,2353,2355,2357,2361,2365,2367,2369,2370,2374,2378],{"path":44,"title":45,"date":2343,"pinned":15},"2022-10-24",{"path":39,"title":2345,"date":2346,"pinned":15},"JavaScript 基础","2023-11-24",{"path":2328,"title":2329,"date":2348,"pinned":15},"2025-06-21",{"path":2350,"title":2351,"date":2352,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdesign","设计模式","2021-10-05",{"path":2320,"title":2321,"date":2354,"pinned":15},"2025-07-10",{"path":2316,"title":2317,"date":2356,"pinned":15},"2026-06-25",{"path":2358,"title":2359,"date":2360,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fevent-loop","异步编程与事件循环","2020-03-23",{"path":2362,"title":2363,"date":2364,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fexec","正则表达式","2022-05-21",{"path":2336,"title":2337,"date":2366,"pinned":15},"2024-07-10",{"path":2324,"title":2325,"date":2368,"pinned":15},"2025-07-04",{"path":7,"title":8,"date":14,"pinned":15},{"path":2371,"title":2372,"date":2373,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fproxy","代理与反射","2022-10-23",{"path":2375,"title":2376,"date":2377,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fsafe","安全","2023-06-26",{"path":2332,"title":2333,"date":2379,"pinned":15},"2025-01-29",{"path":2324,"title":2325,"date":2368,"pinned":15},{"path":2371,"title":2372,"date":2373,"pinned":15}]