javascript 原型链和闭包问题
怪我咯
怪我咯 2017-04-11 11:41:06
[JavaScript讨论组]
    function Person(first, last) {
        var fName = first;
        var lName = last;

        function firstName(first) {
            return first ? (fName = first) : fName;
        };

        function lastName(last) {
            return last ? (lName = last) : lName;
        };

        return {
            firstName: firstName,
            lastName: lastName
        }
    }
    Person.prototype = {
        show: function() {
            console.log("show");
        }
    }

    var person = new Person("michael", "jackson");
    console.log(person);

    function Book(name, author) {
        this.name = name;
        this.author = author;
    };
    Book.prototype = {
        show: function() {
            console.log("show");
        }
    }
    var book = new Book("java", "me");
    console.log(book);

代码如上图,Person类我使用闭包的方式创建实现private,Book类使用原型的方式创建,当我在给原型添加方法的时候,为什么Person类添加不了,Book类就可以添加成功

怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(7)
迷茫
    function Person(first, last) {
        var fName = first;
        var lName = last;

        function firstName(first) {
            return first ? (fName = first) : fName;
        };

        function lastName(last) {
            return last ? (lName = last) : lName;
        };

        this.firstName = firstName
        this.lastName = lastName
    }
怪我咯

我一般用闭包的封装一个模块,return出来接口(暴露接口),然后调用。
你发现,return出来的是一个对象,所以而不是用构造函数生成的对象,你只是用函数去生成对象。
发现自己解释不清楚,等待其他答案。

大家讲道理

在new function()的时候,如果function的返回值是对象的话则返回该对象,否则返回function的实例
你的Person的返回值是个字面量对象,因此你的person变量是一个字面量对象,而不是Person的实例,所以没有Person中的原型方法
浏览器控制台数据结果也能看出来(贴图比较麻烦,就把结果粘贴过来了)
返回字面量对象的结果:
Object {}

firstName: firstName(first)
lastName: lastName(last)
__proto__: Object

如果是Person的实例话,结果如下:
Person

__proto__: Object
    show: ()
    __proto__: Object
PHPz

function Person()中你返回了一个object对象,所以在你执行Person.prototype时Person已经不是function (这里指"类")了,而是一个object,而object是没有.prototype一说的。自己也瞧见了,Book中你没有返回对象,所以原型链上有了show方法。 ~~

PHPz

工厂函数和构造函数应该分开,比如你在写Java的时候,一个类的构造函数就不会返回一个对象吧(实际上构造函数是么都返回不了)

你的这种写法叫工厂函数,应该这么用:

function person(first, last) { //《JavaScript语言精粹》中,老道提到,工厂函数最好使用非大写
    var fName = first;
    var lName = last;

    return {
        firstName: function (first) {
            return first ? (fName = first) : fName;
        },
        lastName: function (last) {
            return last ? (lName = last) : lName;
        },
        prototype: {
            show: function() {
                console.log("show");
            }
        }
    }
}

var aPerson = person("michael", "jackson");
console.log(aPerson);
大家讲道理

同意 @iknight 的回答。

函数Person通过new操作符后它是一个构造函数,在构造函数执行的过程中,首先会创建一个新对象object,该对象就是当前实例,而它的所属类的原型指向Person,即object.__proto__ === Person.prototype,最后构造函数默认返回当前实例。

题主这时手动返回一个字面量对象object2,此时它是Object构造函数的实例,所以它的所属类原型应该是指向Object构造函数的原型,即object2.__proto__ === Object.prototype,因此它是不能使用Person.prototype上的方法的

巴扎黑

function foo(){return 1}

var t1=new foo();
typeof t1 === 'number'
说明t1根本不是对象,不管你给foo怎么加原型属性都没用。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号