object.method() 和 object.prototype.method();

发布于 2022-09-03 19:02:13 字数 446 浏览 17 评论 0

原型式继承:

function object(o){
    function clone(){};
    clone.prototype=o;
    return new clone();
}
function parent(name){
  this.position=1;
  this.name=name;
}
parent.prototype.getLevel=function(){
  console.log("hello");
}
var children=object(parent);

这时运行:

children.getLevel(); //children.getLevel is not a function(…)
children.prototype.getLevel();//hello

为什么会产生两种不同的结果?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情绪少女 2022-09-10 19:02:13

一般情况下,一个对象的property属性是一个Object对象。而在上面的例子中,你在给clone的property属性赋值时,直接赋了一个Function对象(这里是parent),从而导致你的children__proto__属性为parent方法。

console.log(children.__proto__);//[Function:parent]

__proto__属性是原型继承核心所在。
在你的程序中children是一个实例对象,实例对象是没有prototype属性的(后面会有解释为什么你依然输出了hello)。
在你调用children.getLevel();方法时,程序首先在实例的属性中寻找,发现没有此方法,然后会到实例的原型中去寻找,这个传递正是依赖了__proto__属性.重点就在这里:,这里的__proto__属性已经被你指明了是个Function对象,也就是parent方法,而在parent方法中并没有getLevel(这里你将方法定义在了parentprototype中),程序会继续沿着__proto__(原型链的真正作用链)向上搜索,当然再向上就是function(),Object,最后没有找到getLevel方法,只能返回undefined。重点还在这里:,在执行children.prototype.getLevel();时,同样在children这个实例属性中没有prototype属性(因为children是个空的实例对象,只有__proto__属性),这时就也要通过__proto__搜索原型链,这时奇怪的事情就出现了,在__proto__中有个prototype属性(其实就是parent方法下面的prototype),搜索到property之后,就自然而然的找到你在parentproperty下面定义的getLevel方法了,执行输出结果。
想要通过children.getLevel();方法得带结果,按照上面的思路可以添加这样的定义:

parent.getLevel = function(){
    console.log("this is xiaoyaoxiang");
}

结果如下:

children.getLevel();//this is xiaoyaoxiang;

注:对于一般的实例而言,是没有prototype属性的。以下可以验证:

function clon(){};
var a = new clon();
console.log(a.prototype);//undifined.

这上面的a就等同于你得到的childrenchildren作为clone()的一个实例,也理所当然没有prototype属性。所以两个方法的执行都需要在原型链上搜索。

正确的原型式继承方法:(父类无需创建构造函数,是一种简单的继承方式)

    function object(o){
        var clone = function(){}
        clone.prototype=o;
        return new clone();
    }
    var parent = {
        name: "xiaoyaoxiang",
        getLevel:function(){
            console.log("this is " + this.name);
        }
    }

    var children = object(parent);
    children.getLevel();

当然了,你的继承方法修改一下也就是非常常用的继承方法:

   function object(o){
        var clone = function(){}
        clone.prototype=o;
        return new clone();
    }

    function parent(){}
    parent.prototype = {
        name:"xiaoyaoxiang",//将私有变量局定义在原型链上,(这个取决于是否想让子类访问)
        getLevel:function(){
            console.log("this is "+ this.name);
        }
    }

    var children = object(parent.prototype);//将parent的prototype传进去
    children.getLevel();
    console.log(children.name);

如果对你有所帮助,欢迎采纳

随心而道 2022-09-10 19:02:13

因为你继承的方式写错了 clone.prototype=o; 改为 clone.prototype=new o();函数的prototype应该是一个对象,你直接赋成了一个函数,可能使js不能识别其为真正的prototype,而只是一个叫做‘prototype’的属性而已。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文