为什么无法更改 JS 的构造函数呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
tianzhen
V2EX    Javascript

为什么无法更改 JS 的构造函数呢?

  •  
  •   tianzhen 2016-01-13 22:11:50 +08:00 3539 次点击
    这是一个创建于 3569 天前的主题,其中的信息可能已经有所发展或是发生改变。
    var Person = function(name) { this.name = name }; var foo = new Person("foo"); foo // { name: 'foo' } foo.constructor.toString() // 'function (name) { this.name = name }' Person.prototype.constructor.toString() // 'function (name) { this.name = name }' // 改写 constructor 指向的构造函数 Person.prototype.constructor = function(name) { this.name = "bar" } Person.prototype.constructor.toString() // 'function (name) { this.name = "bar" }' var foo2 = new Person("foo2"); foo2.constructor.toString() // 'function (name) { this.name = "bar" }' // 期待是 { name: 'bar' } 因为构造函数已变了 // 但是... foo2 // { name: 'foo2' } 
    15 条回复    2016-01-14 15:26:13 +08:00
    iwege
        1
    iwege  
       2016-01-13 22:18:13 +08:00   1
    在最后试试 Person.toString() 看看。
    Person 本来就是一个 function 了。 要改变的话直接赋值 Person = func 就好了。
    tianzhen
        2
    tianzhen  
    OP
       2016-01-13 22:24:47 +08:00
    @iwege 原来如此,貌似我那样做只是把 Person.prototype 对象给改写了

    ```Javascript
    // 原本
    Person === Person.prototype.constructor // true
    // 改写后
    Person === Person.prototype.constructor // false
    Person.toString(); // 依旧是 'function (name) { this.name = name }'
    ```
    banricho
      &nsp; 3
    banricho  
       2016-01-14 00:58:56 +08:00   1
    1. 函数都有 prototype 对象,其中默认包含一个属性 constructor ,一般情况下默认指向函数自身
    2. 以你的例子来说, foo1. __proto__ === Person.prototype ,修改 constructor 是没有用的,它只是一个天生就默认存在的标志,但本身不具备实际意义
    3. 你的任何实例化方法本身不存在 toString 方法,那么就会向构造函数 Person 上查找。没有的话就继续向 Function.prototype 上查找,还是没有就继续在 Function.prototype.__proto__ 也就是 Object.prototype 上查找,于是你里面所有的 toString 其实最终调用的都是 Object.prototype.toString 方法
    4. 要达到你的效果修改 constructor 是没用的,关键是要在 foo1 和 foo2 之间切断原型链
    banricho
        4
    banricho  
       2016-01-14 00:59:58 +08:00   1
    @banricho “那么就会向构造函数 Person 上查找” => “那么就会向构造函数 Person.prototype 上查找”
    banricho
        5
    banricho  
       2016-01-14 01:12:32 +08:00   1
    我搞错了,请看下面的

    var Person = function(name) {
    this.name = name
    };

    var foo = new Person("foo");

    console.log(foo.toString === Person.prototype.toString); // true
    console.log(Person.prototype.toString === Person.prototype.__proto__.toString); // true
    console.log(Person.prototype.__proto__.toString === Object.prototype.toString); // true

    console.log(Person.toString === Function.prototype.toString); // true
    console.log(Function.prototype.toString === Object.toString); // true

    我上面说的第 3 点有误。。。
    banricho
        6
    banricho  
       2016-01-14 01:20:35 +08:00   1
    还得补上这个 = =。

    console.log(Person.toString === Function.prototype.toString); // true
    console.log(Function.prototype.toString === Object.toString); // true
    console.log(Function.prototype.toString === Function.toString); // true
    console.log(Function.toString === Object.toString); // true
    console.log(Function.__proto__ === Object.__proto__); // true

    好微妙的关系(好了我去睡了,大晚上脑子混乱又乱扯了。。。)
    banricho
        7
    banricho  
       2016-01-14 04:02:49 +08:00   1
    没睡着 =。= 爬起来**貌似**搞清了,直接上图

    banricho
        8
    banricho  
       2016-01-14 04:08:44 +08:00   1
    @banricho 真去睡了
    大晚上脑子果然不清醒

    Function.prototype.__proto__ 指向的应该是 Object.prototype 而不是 Person 的。。。
    啊啊啊啊啊啊啊啊 救命啊好丢人
    banricho
        9
    banricho  
       2016-01-14 04:25:45 +08:00   2
    补完睡觉,刷屏抱歉

    starAsh
        10
    starAsh  
       2016-01-14 09:29:24 +08:00
    @banricho 能够见到这么认真的回复以及对技术的认真态度,小弟膜拜
    tianzhen
        11
    tianzhen  
    OP
       2016-01-14 09:34:05 +08:00
    @banricho Orz 膜拜!您的全部回复都给了感谢!
    SpicyCat
        12
    SpicyCat  
       2016-01-14 10:22:23 +08:00
    @banricho 这图用什么工具画的,太厉害了
    banricho
        13
    banricho  
       2016-01-14 10:29:50 +08:00
    @starAsh 并没有认真啦,就是有点强迫症 >w<

    @tianzhen 谢谢哈~~受宠若惊

    @SpicyCat 用的是 iOS 上的 Paper 53 ,然后扔电脑上用了 Pixelmator 加了个字 -_- ||
    SilentDepth
        14
    SilentDepth  
       2016-01-14 13:22:52 +08:00
    @banricho 正纳闷这浓浓的 Paper 感是怎么揉进文字的,原来还有后期……
    banricho
        15
    banricho  
       2016-01-14 15:26:13 +08:00 via Android
    @SilentDepth 哈哈哈
    就是写字不方便,没文字总画错
    准备入手个手写笔试试写字
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1156 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 17:57 PVG 01:57 LAX 10:57 JFK 13:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86