精华内容
下载资源
问答
  • prototype和__proto__都有一个...那什么情况下会出现prototype和__proto__的constructor指向错误呢?上代码上图! js代码: function Stu(uname,age) { this.uname=uname; this.age=age; } Stu.prototype={ dan...

    prototype和__proto__都有一个constructor属性,且指向原来的构造函数。那什么情况下会出现prototype和__proto__的constructor指向错误呢?上代码上图!


    js代码:


    function Stu(uname,age) {
        this.uname=uname;
        this.age=age;
    }
    Stu.prototype={
        dance:function () {
            console.log('你好,我跳舞');
        },
        sing:function () {
        console.log('你好,我没有在唱歌');
        }
    };
    var ming=new Stu('李明',20);
    console.log(ming.__proto__.constructor);
    console.log(Stu.prototype.constructor);
    

    结果图:


    在这里插入图片描述
    由图可以知prototype和__proto__的constructor属性指向错误并没有指向原来的构造函数Stu,为什么呢?
    这是因为

    Stu.prototype={
        dance:function () {
            console.log('你好,我跳舞');
        },
        sing:function () {
        console.log('你好,我没有在唱歌');
        }
    };
    

    上图中,把一个对象赋值给了Stu.prototype,所以prototype和__proto__的指向就是这个对象了,那么怎么让它指回原来的构造函数呢?
    只需要

    Stu.prototype={
        constructor:Stu,
        dance:function () {
            console.log('你好,我跳舞');
        },
        sing:function () {
        console.log('你好,我没有在唱歌');
        }
    };
    

    即可


    效果图:


    在这里插入图片描述
    大功告成!
    本文只用于个人学习和记录

    展开全文
  • js中constructor指向问题

    2019-12-27 20:49:44
    首先用一个例子指出来constructor存在形式。...由上面的代码我们总结出结论1:上面的代码在控制台可以看出constructor指向构造器Fruit的引用。 function Fruit(){ this.name=“火龙果”} //va...

    首先用一个例子指出来constructor存在形式。

    function Fruit(){ }
    var f=new Fruit();
    console.log(f.constructor);//打印出Fruit()
    由上面的代码我们总结出结论1:上面的代码在控制台可以看出constructor是指向构造器Fruit的引用。

    function Fruit(){ this.name=“火龙果”}
    //var f=new Fruit();
    function Apple(){this.name=“苹果”;}
    Apple.prototype=new Fruit();
    var apple=new Apple();
    console.log(apple.constructor);//依然打印出Fruit()
    Apple.prototype={};//空对象的构造器是Object()
    apple=new Apple();
    console.log(apple.constructor);//指向Object()

    这个地方就有点奇怪了。这个constructor到底指向的是那个实例的构造器?

    根据上面的代码总结出结论2:constructor指向的是原型对象的构造器的引用

    即 apple.constructor==Apple.prototype.constructor

    var apple2=new apple.constructor();
    console.log(apple2.name);
    或者

    var apple2=new Apple.prototype.constructor();
    console.log(apple2.name);
    打印的都是火龙果。

    我们现在想让他执行的是苹果的打印;这个时候就需要对constructor的指向进行重新指定。

    根据上面的两个结论:无论是修改实例的constructor还是构造器的原型constructor属性都是可以达到目的的;

    可以在重写了prototype属性的代码后写下这样的代码

    Apple.prototype.constructor=Apple;
    或者在实例化后对实例的constructor进行重新制定。

    apple.constructor=Apple;
    虽然上面的两种方式都能达到目的,但是推荐使用第一种。

    第二种方式需要有一个实例化的对象,而我们只用在对继承的创建完成后才会去实例化,

    等有了实例化对象在去修改constructor,这个时候已经迟了,意义已经不大了,继承的关系已经确定了。

    展开全文
  • constructor 的含义是 返回指向创建了该对象原型的函数引用. instanceof检测对象的原型链,通常你是无法修改的(不过某些引擎通过私有的__proto__属性暴露出来)。 constructor其实没有什么用处,只是JavaScript...

    让我们先来了解一下constructor

    1. constructor属性不影响任何JavaScript的内部属性。
    2. constructor 的含义是 返回指向创建了该对象原型的函数引用.
    3. instanceof检测对象的原型链,通常你是无法修改的(不过某些引擎通过私有的__proto__属性暴露出来)。
    4. constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。
    5. 由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。
    6. 不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。
     class Person {
    
        }
        class Friend extends Person {
    
        }
        console.log('%O', Person.prototype.constructor); // Person
        console.log('%O', Friend.prototype.constructor); // Friend
    
    //Friend.prototype.constructor = Friend 
    //原先Friend.prototype.constructor指向的是Person
    //但是感觉并没有什么用有没有弹出的结果都一样,感觉都很好完成了继承
    //但是在后续实例化等过程中不会直接使用到constructor,但是出于对该函数本身的含义的理解,于是我们修正了constructor。
    

        修正constructor是为了保证它能按照constructor被设计的意义一样正确的指向构造函数,如果constructor正确指向构造函数,就意味着能获取到构造函数的prototype,拿到prototype,你就可以为所欲为了,但是又因为constructor的指向不是强制的,所以如果你要用constructor做什么事要小心,因为它一不定严格指向该对象的构造函数,所以这边你修改不修改没有什么强制性。

     

    var f = (function() {
        function Person() {
        
        }
        
        function Friend() {
        
        }
        
        Friend.prototype = new Person();
        // Friend.prototype.constructor = Friend;
        return new Friend();
    }())
    
    // 如果需要扩展原型方法
    f.constructor.prototype.sayHello = function() {
        console.log('hello');
    }
    f.sayHello(); // hello
    console.log(f);

    通过上面的例子可以看出修正了的constructor与没有修改的差别是扩展的sayHello方法在原型链上加的位置不一样了。

    展开全文
  • 由于实例对象继承自原型对象,所以实例对象中也具有constructor属性,指向与原型对象中的constructor一样 一、发现 对于一些公共的属性和方法,我么可以通过原型对象,把它们定义在构造函数的外部,使构造函数成为...

    首先,对constructor属性有以下几点了解:

    1. constructor属性是原型对象具有的属性,指向通过prototype户型链接它的构造函数
    2. 由于实例对象继承自原型对象,所以实例对象中也具有constructor属性,指向与原型对象中的constructor一样;
    3. 其实构造函数(无论是原生的还是自定义的)也有constructor属性,它们统统指向原生的Function构造函数,就连Function自己的构造函数也是它自己

    一、发现

    对于一些公共的属性和方法,我么可以通过原型对象,把它们定义在构造函数的外部,使构造函数成为一个空函数:

    function Person(){}
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    

    但是,这样的话,每增加一个公共的属性或方法都得写上Person.prototype。为了减少重复的书写,更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象

    function Person(){}
    Person.prototype = {
        name : "Nicholas",
        age : 29,
        job: "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    

    经过这样重写之后,从视觉上更好的封装原型的功能,我们相当于把Person.prototype设置成了一个以对象字面量形式创建的新对象。
    但是,这样设置有一个问题:constructor属性不再指向person了

    var friend = new Person();
    alert(friend instanceof Person); //true
    alert(friend.constructor == Person); //false
    

    我们可以看到,instanceof表示friend仍然是Person的实例,但是constructor却表明friend的构造函数(父类)不再是Person了,constructor与instanceof的结果不一致这就造成了instanceof的失真。那么对象的constructor到底指向谁呢?

    二、解答

    var friend = new Person();
    alert(friend.constructor == Person); //false
    alert(friend.constructor == Object); //true
    

    没错,constructor 属性指向了Object ,也就是说通过这种对象字面量方式改变原型对象之后,原型/实例对象的constructor属性指向了Object,它们的构造函数(父类)变成了Object。
    这是为什么呢?
    每创建一个函数就会同时创建它的prototype对象,这个对象也会自动获得constructor属性。而通过对象字面量形式改写原型对象,本质上算是完全重写了默认的原型对象,也即是说我们写了一个新的对象,它是个新对象,因此它的constructor属性也就变成了新对象的constructor属性,指向Object构造函数,不再指向Person函数了。
    因此,通过constructor操作符还能返回正确的结果,但是通过instanceof不能准确确定对象的类型

    var friend = new Person();
    alert(friend instanceof Object); //true
    alert(friend instanceof Person); //true
    alert(friend.constructor == Person); //false
    alert(friend.constructor == Object); //true
    

    三、带来的后果&根本原因

    通过改写原型对象的方式改变属性和方法,不仅使instanceof操作符失真,如果实例对象定义在修改之前,还会导致实例对象无法访问新加的属性和方法:

    var friend = new Person();
    Person.prototype.sayHi = function(){
    	alert("hi");
    };
    friend.sayHi(); //"hi"(没有问题!)
    

    这段代码显示,通过使用Person.prototype.……的方式逐个向原型对象上添加的属性,可以被实例对象成果访问;但是,通过改写原型对象的形式添加新属性和方法并非如此:

    function Person(){}
    var friend = new Person();
    Person.prototype = {
    	constructor: Person,
    	name : "Nicholas",
    	age : 29,
    	job : "Software Engineer",
    	sayName : function () {
    		alert(this.name);
    	}
    };
    friend.sayName(); //error
    

    显然,通过改写原型对象的方式,实例对象不能访问新添加的属性和方法。导致这一现象的根本原因和instanceof操作符失真的原因一致:constructor的指向发生了变化
    请参考以下图示:

    简单来讲,调用构造函数时,会为实例添加一个指向最初原型的_proto_指针,重写原型对象成为一个新对象,就等于:

    1. 切断了构造函数与最初原型之间的联系,切断后constructor默认指向Object,但可以自定义修改;
    2. 切断了新原型与之前已经存在的任何实例对象之间的联系,即新原型不是任何已有实例的原型对象
    3. 实例对象的_proto_属性指向的仍然是原有的原型对象。

    四、小结

    1.常规写法,但是比较啰嗦,每次都要重复写Person.prototype

    function Person(){}
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    //...
    

    2.使用对象字面量方式改写原型对象,但是这样会改变constructor的指向

    function Person(){}
    Person.prototype = {
        name : "Nicholas",
        age : 29,
      //...
    };
    

    3.如果 constructor 的值真的很重要,可以像下面这样特意将它设置回适当的值。

    function Person(){}
    Person.prototype = {
        constructor : Person,
        name : "Nicholas",
        age : 29,
      //...
    };
    

    在代码中特意包含一个 constructor属性,并将它的值设置为Person,从而确保了通过该属性能够访问到适当的值

    4.但是以上述形式重新指定constructor属性,会使得constructor属性的[[Enumerable]]特性被设置为 true,也就是变成了可枚举类型的属性,但是原生的constructor属性是不可枚举类型,[[Enumerable]]特性为 false,因此可使用下列语句修改它的[[Enumerable]]属性,仍符合原生的设定:

    function Person(){}
    Person.prototype = {
        name : "Nicholas",
        age : 29,
        job : "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    //重设构造函数,只适用于 ECMAScript 5 兼容的浏览器
    Object.defineProperty(Person.prototype, "constructor", {
        enumerable: false,
        value: Person
    });
    
    所有笔记仅作个人整理 ,内容参考自以下来源:
    1. 《JavaScript高级程序设计(第三版)》
    展开全文
  • Chrome中调试 源码: 构造器 function Dog(){this.tail=true} 构造新实例 var benji= new Dog();...新实例的constructor benji.constructor //ƒ Dog(){this.tail=true}Dog 在原型中添加方法 Dog.prototype.s...
  • 我们都知道 ECMAScript中 Object是所以引用类型的基类型 也就是所以引用类型都继承自Object的默认属性和方法,prototype是函数的熟悉 Object.prototype指向所有引用类型的根对象 constructor指向构造方法...
  • 但是我们在使用构造函数时,一般会重写它的原型,会导致constructor指向出问题。 问题二 :在重写原型对象之后,重写之前的原型对象到哪去了? function Animal() {} Animal.prototype.say = f...
  • constructor

    2010-03-20 11:35:28
    prototype默认有个constructor属性,而constructor指向构造函数。 随着prototype被继承,constructor也被继承了下来。 也就是说new一个对象时,constructor由prototype(是一个对象)决定,因为constructor是...
  • JS constructor

    2019-07-09 01:12:48
    1.每个对象都有一个constructor,都指向创建该对象的方法。 2.function对象的prototype的constructor也是... 显性添加constructor指向其函数对象。 参考:http://blog.csdn.net/chunqiuwei/article/details/2209255...
  • function Odemo1(){} Odemo1.prototype.sayName=function(){} function Odemo2(){} ... Odemo2.prototype=new Odemo1();...说白了,为什么a.constructor指向的是Odemo1 a不是Odemo2的实例对象么?
  • JavaScript类和继承:constructor属性2009-07-08 17:51 sanshi 博客园 我要评论(1) 字号:T | T本文介绍了JavaScript里面的constructor属性...AD: constructor属性始终指向创建当前对象的构造函数。比如下面例子
  • var arr = [1, 56, 34, 12];...console.log(arr.constructor === Array);  Foo = function() { };  console.log(Foo.constructor === Function);  var obj = new Foo();  //alert(obj); console.log(obj.const
  • // 构造函数Person function Person(name, age) { this.age = age; this.name = name;...// 验证:实例对象p的constructor属性指向构造函数Person var p = new Person("张三", 18); console.log(p.constructor ===
  • JavaScript Constructor

    2010-12-13 17:00:00
    构造函数都有一个prototype属性,它是一个Object对象,此对象还有一个可以手动维护的constructor属性(constructor指向本身,只是维护一种结构,目前没有发现它有什么用)和一个隐含的指向父构造函数的prototype属性...
  • 这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数,这个时候我们修改这个函数的prototype时,就发生了意外。如 function Person(name,age){ this.name = name; this...
  • javascript中的constructor

    2017-03-05 23:34:30
    javascript中的constructorjavascript的函数拥有 ... .constructor默认指向Function对象; .prototype.constructor 默认指向函数本身。javascript的对象只拥有一个 .constructor 属性。 .constructor 指向该对象的构造函
  • 这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数,这个时候我们修改这个函数的prototype时,就发生了意外。如 function Person(name,age){ this.name = name; ...
  • JS原型中的constructor属性 ...这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数,这个时候我们修改这个函数的prototype时,就发生了意外。 例: function Person(n
  • 如题

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 110,080
精华内容 44,032
关键字:

constructor指向