首页IT科技原型继承的优缺点(原型&继承题目及内容解答)

原型继承的优缺点(原型&继承题目及内容解答)

时间2025-04-28 18:02:00分类IT科技浏览3098
导读:这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助...

这里给大家分享我在网上总结出来的一些知识          ,希望对大家有所帮助

这道义题目考察原型           、原型链的基础                 ,记住就可以了           。

2. 代码输出结果

// a function Foo () { getName = function () { console.log(1); } return this; } // b Foo.getName = function () { console.log(2); } // c Foo.prototype.getName = function () { console.log(3); } // d var getName = function () { console.log(4); } // e function getName () { console.log(5); } Foo.getName(); // 2 getName(); // 4 Foo().getName(); // 1 getName(); // 1 new Foo.getName(); // 2 new Foo().getName(); // 3 new new Foo().getName(); // 3

输出结果:2 4 1 1 2 3 3

解析:

Foo.getName()      ,Foo为一个函数对象          ,对象都可以有属性                ,b 处定义Foo的getName属性为函数      ,输出2; getName()     ,这里看d                、e处                ,d为函数表达式           ,e为函数声明     ,两者区别在于变量提升                ,函数声明的 5 会被后边函数表达式的 4 覆盖; Foo().getName()           ,这里要看a处,在Foo内部将全局的getName重新赋值为 console.log(1) 的函数                ,执行Foo()返回 this                 ,这个this指向window,Foo().getName() 即为window.getName()          ,输出 1; getName()                 ,上面3中      ,全局的getName已经被重新赋值          ,所以这里依然输出 1; new Foo.getName()                ,这里等价于new (Foo.getName())      ,先执行 Foo.getName()     ,输出 2                ,然后new一个实例; new Foo().getName()           ,这里等价于 (new Foo()).getName(), 先new一个Foo的实例     ,再执行这个实例的getName方法                ,但是这个实例本身没有这个方法           ,所以去原型链__protot__上边找,实例.__protot__ === Foo.prototype                ,所以输出 3; new new Foo().getName()                 ,这里等价于new (new Foo().getName()),如上述6          ,先输出 3                 ,然后new 一个new Foo().getName() 的实例                。

3. 代码输出结果

var F = function() {}; Object.prototype.a = function() { console.log(a); }; Function.prototype.b = function() { console.log(b); } var f = new F(); f.a(); f.b(); F.a(); F.b()

输出结果:

a Uncaught TypeError: f.b is not a function a b

解析:

f 并不是 Function 的实例      ,因为它本来就不是构造函数          ,调用的是 Function 原型链上的相关属性和方法                ,只能访问到 Object 原型链      。所以 f.a() 输出 a       ,而 f.b() 就报错了     。 F 是个构造函数     ,而 F 是构造函数 Function 的一个实例                。因为 F instanceof Object === true                ,F instanceof Function === true           ,由此可以得出结论:F 是 Object 和 Function 两个的实例     ,即 F 能访问到 a                , 也能访问到 b           。所以 F.a() 输出 a            ,F.b() 输出 b     。

4. 代码输出结果

function Foo(){ Foo.a = function(){ console.log(1); } this.a = function(){ console.log(2) } } Foo.prototype.a = function(){ console.log(3); } Foo.a = function(){ console.log(4); } Foo.a(); let obj = new Foo(); obj.a(); Foo.a();

输出结果:4 2 1

解析:

Foo.a() 这个是调用 Foo 函数的静态方法 a,虽然 Foo 中有优先级更高的属性方法 a                ,但 Foo 此时没有被调用                 ,所以此时输出 Foo 的静态方法 a 的结果:4 let obj = new Foo(); 使用了 new 方法调用了函数,返回了函数实例对象          ,此时 Foo 函数内部的属性方法初始化                 ,原型链建立                。 obj.a() ; 调用 obj 实例上的方法 a      ,该实例上目前有两个 a 方法:一个是内部属性方法          ,另一个是原型上的方法           。当这两者都存在时                ,首先查找 ownProperty       ,如果没有才去原型链上找     ,所以调用实例上的 a 输出:2 Foo.a() ; 根据第2步可知 Foo 函数内部的属性方法已初始化                ,覆盖了同名的静态方法           ,所以输出:1

5. 代码输出结果

function Dog() { this.name = puppy } Dog.prototype.bark = () => { console.log(woof!woof!) } const dog = new Dog() console.log(Dog.prototype.constructor === Dog && dog.constructor === Dog && dog instanceof Dog)

输出结果:true

解析:

因为constructor是prototype上的属性     ,所以dog.constructor实际上就是指向Dog.prototype.constructor;constructor属性指向构造函数。instanceof而实际检测的是类型是否在实例的原型链上                。

constructor是prototype上的属性                ,这一点很容易被忽略掉                。constructor和instanceof 的作用是不同的           ,感性地来说,constructor的限制比较严格                ,它只能严格对比对象的构造函数是不是指定的值;而instanceof比较松散                 ,只要检测的类型在原型链上,就会返回true。

6. 代码输出结果

var A = {n: 4399}; var B = function(){this.n = 9999}; var C = function(){var n = 8888}; B.prototype = A; C.prototype = A; var b = new B(); var c = new C(); A.n++ console.log(b.n); console.log(c.n);

输出结果:9999 4400

解析:

console.log(b.n)          ,在查找b.n是首先查找 b 对象自身有没有 n 属性                 ,如果没有会去原型(prototype)上查找      ,当执行var b = new B()时          ,函数内部this.n=9999(此时this指向 b) 返回b对象                ,b对象有自身的n属性      ,所以返回 9999           。 console.log(c.n)     ,同理                ,当执行var c = new C()时           ,c对象没有自身的n属性     ,向上查找                ,找到原型 (prototype)上的 n 属性           ,因为 A.n++(此时对象A中的n为4400), 所以返回4400                。

7. 代码输出问题

function A(){ } function B(a){   this.a = a; } function C(a){   if(a){ this.a = a;   } } A.prototype.a = 1; B.prototype.a = 1; C.prototype.a = 1; console.log(new A().a); console.log(new B().a); console.log(new C(2).a);

输出结果:1 undefined 2

解析:

console.log(new A().a)                ,new A()为构造函数创建的对象                 ,本身没有a属性,所以向它的原型去找          ,发现原型的a属性的属性值为1                 ,故该输出值为1; console.log(new B().a)      ,ew B()为构造函数创建的对象          ,该构造函数有参数a                ,但该对象没有传参      ,故该输出值为undefined; console.log(new C(2).a)     ,new C()为构造函数创建的对象                ,该构造函数有参数a           ,且传的实参为2     ,执行函数内部                ,发现if为真           ,执行this.a = 2,故属性a的值为2      。

8 代码输出问题

function Parent() { this.a = 1; this.b = [1, 2, this.a]; this.c = { demo: 5 }; this.show = function () { console.log(this.a , this.b , this.c.demo ); } } function Child() { this.a = 2; this.change = function () { this.b.push(this.a); this.a = this.b.length; this.c.demo = this.a++; } } Child.prototype = new Parent(); var parent = new Parent(); var child1 = new Child(); var child2 = new Child(); child1.a = 11; child2.a = 12; parent.show(); child1.show(); child2.show(); child1.change(); child2.change(); parent.show(); child1.show(); child2.show();

输出结果:

parent.show(); // 1 [1,2,1] 5 child1.show(); // 11 [1,2,1] 5 child2.show(); // 12 [1,2,1] 5 parent.show(); // 1 [1,2,1] 5 child1.show(); // 5 [1,2,1,11,12] 5 child2.show(); // 6 [1,2,1,11,12] 5

这道题目值得神帝,他涉及到的知识点很多                ,例如this的指向      、原型     、原型链                、类的继承           、数据类型等           。

解析

parent.show()                 ,可以直接获得所需的值,没啥好说的; child1.show()          ,Child的构造函数原本是指向Child的                 ,题目显式将Child类的原型对象指向了Parent类的一个实例      ,需要注意Child.prototype指向的是Parent的实例parent          ,而不是指向Parent这个类                。 child2.show()                ,这个也没啥好说的; parent.show()      ,parent是一个Parent类的实例     ,Child.prorotype指向的是Parent类的另一个实例                ,两者在堆内存中互不影响           ,所以上述操作不影响parent实例     ,所以输出结果不变; child1.show()                ,child1执行了change()方法后           ,发生了怎样的变化呢? this.b.push(this.a),由于this的动态指向特性                ,this.b会指向Child.prototype上的b数组,this.a会指向child1a属性,所以Child.prototype.b变成了[1,2,1,11]; this.a = this.b.length                 ,这条语句中this.athis.b的指向与上一句一致,故结果为child1.a变为4; this.c.demo = this.a++          ,由于child1自身属性并没有c这个属性                 ,所以此处的this.c会指向Child.prototype.c      ,this.a值为4          ,为原始类型                ,故赋值操作时会直接赋值      ,Child.prototype.c.demo的结果为4     ,而this.a随后自增为5(4 + 1 = 5)      。 child2执行了change()方法, 而child2child1均是Child类的实例                ,所以他们的原型链指向同一个原型对象Child.prototype,也就是同一个parent实例           ,所以child2.change()中所有影响到原型对象的语句都会影响child1的最终输出结果     。 this.b.push(this.a)     ,由于this的动态指向特性                ,this.b会指向Child.prototype上的b数组,this.a会指向child2a属性,所以Child.prototype.b变成了[1,2,1,11,12]; this.a = this.b.length           ,这条语句中this.athis.b的指向与上一句一致,故结果为child2.a变为5; this.c.demo = this.a++                ,由于child2自身属性并没有c这个属性                 ,所以此处的this.c会指向Child.prototype.c,故执行结果为Child.prototype.c.demo的值变为child2.a的值5          ,而child2.a最终自增为6(5 + 1 = 6)                。

9. 代码输出结果

function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); console.log(instance.getSuperValue());

输出结果:true

实际上                 ,这段代码就是在实现原型链继承      ,SubType继承了SuperType          ,本质是重写了SubType的原型对象                ,代之以一个新类型的实例           。SubType的原型被重写了      ,所以instance.constructor指向的是SuperType     。具体如下:

如果对您有所帮助     ,欢迎您点个关注                ,我会定时更新技术文档           ,大家一起讨论学习     ,一起进步                。

声明:本站所有文章                ,如无特殊说明或标注           ,均为本站原创发布           。任何个人或组织,在未征得本站同意时                ,禁止复制     、盗用                、采集           、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益                 ,可联系我们进行处理                。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
羊肚菌的功效和用法(羊肚菌的功效(图文)) wordpress安装包(WordPress安装包:打造属于你的个人网站)