javascript instanceof

本文深入探讨了JavaScript中的继承机制,特别是通过原型链实现继承的过程。文中详细解释了如何使用构造函数、原型对象来创建继承关系,并展示了instanceof操作符的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

javascript中的instanceof
http://stackoverflow.com/questions/2449254/what-is-the-instanceof-operator-in-javascript
万能的instanceof公式:

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}
参考JS高级程序设计, this.xx叫构造函数模式,x.prototype叫原型模式
function Animal() {

    this.eat = function(sth) {
        console.log("eat : " + sth);
    }
}
console.log("Animal.prototype=",Animal.prototype)

Animal.prototype.play = function (sth) {
    console.log("play : " + sth);
}

console.log("Animal.prototype=",Animal.prototype)
console.log("Animal.prototype.constructor=",Animal.prototype.constructor)

function Cat() {
    this.miao = function() {
        console.log("miao!");
    }

}
console.log("Cat.prototype=",Cat.prototype)
console.log("Cat.prototype.constructor=",Cat.prototype.constructor)

console.log("==>after Cat.prototype = new Animal()");

Cat.prototype = new Animal();

console.log("Cat.prototype=",Cat.prototype)
console.log("Cat.prototype.__proto__=",Cat.prototype.__proto__)
console.log("Cat.prototype.constructor=",Cat.prototype.constructor);

var c = new Cat();
c.miao();
c.eat("fish")


console.log("**************")
console.log("cat instanceof Cat?");
console.log("Cat.prototype", Cat.prototype);
console.log("c.__proto__=", c.__proto__);
console.log("cat instanceof Cat=", c instanceof Cat);

console.log("**************")
console.log("cat instanceof Animal?");
console.log("Animal.prototype=", Animal.prototype);
console.log("c.__proto__=", c.__proto__);
console.log("c.__proto__.__proto__p", c.__proto__.__proto__);
console.log("cat instanceof Animal=", c instanceof Animal);

以上代码解释了,为什么cat是Cat的实例,同时解释了为什么cat是Animal的实例

需要说明的是cat.__proto__始终指向Cat.prototype
__proto__是实例的属性, prototype是类的属性


待研究

function Animal() {

    this.eat = function(sth) {
        console.log("eat : " + sth);
    }
}

Animal.prototype.play = function (sth) {
    console.log("play : " + sth);
}

function Cat() {
    this.miao = function() {
        console.log("miao!");
    }

}

Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

var cat = new Cat();

console.log(cat instanceof Animal);
console.log(cat instanceof Cat);

cat.eat("mouse");
cat.play("ball");
cat.miao();


function Dog() {
    this.wang = function() {
        console.log("wang!");
    }
}

console.log("Dog.prototype=",Dog.prototype);
console.log("Dog.prototype.constructor=",Dog.prototype.constructor);

function F(){}
console.log("F.prototype=",F.prototype);
console.log("F.prototype.constructor=",F.prototype.constructor);

console.log("==>after F.prototype = Animal.prototype")
F.prototype = Animal.prototype;
console.log("F.prototype=",F.prototype);
console.log("F.prototype.constructor=",F.prototype.constructor);

Dog.prototype = new F();
console.log("==>after Dog.prototype = new F()")
console.log("Dog.prototype=",Dog.prototype);
console.log("Dog.prototype.constructor=",Dog.prototype.constructor);

console.log("==>after Dog.prototype.constructor = Dog");
Dog.prototype.constructor = Dog;
console.log("Dog.prototype=",Dog.prototype);

var dog = new Dog();
console.log("==>instanceof?")
console.log("Animal.prototype=",Animal.prototype);
console.log("Dog.prototype=",Dog.prototype);
console.log("dog.__proto__=",dog.__proto__);
console.log("dog.__proto__.__proto__=",dog.__proto__.__proto__);
console.log(dog instanceof Animal);


console.log(dog instanceof Dog);
dog.play("ball2");
dog.wang();
dog.eat("bone");

Di: http://bonsaiden.github.io/JavaScript-Garden/zh/ Di: typeof Di: instanceof Di: arguments Di: arguments.callee



疑问:第20行修正Cat原型上的constructor有什么意义?

(暂时还没发现contructor有什么用,根据图解,它始终指向类定义, ...)

new Aminal的返回值等于Animal.prototype?
console.log(new Animal())
console.log(Animal.prototype)
console.log(new Animal() == Animal.prototype)

测试的结果很明显,Animal.prototype是new Animal的子集, new Animal多出了eat方法. 即
new Xxx() = {method | method∈this ∪ method∈ Xxx.prototype}
哈,这解释了,为什么dog没有eat方法 (dog的prototype指向Animal.prototype而不是new Animal()).

把原型指向构造函数!!

function Foo() {}
function Bar() {}
function Bar2() {}


Bar.prototype = Foo;
Bar2.prototype= new Foo();

var b = new Bar();
var b2 = new Bar2();

console.log("Foo.prototype=",Foo.prototype); //Foo{}
console.log("Bar.prototype=",Bar.prototype); //Foo()
console.log("Bar.prototype.prototype=",Bar.prototype.prototype); //Foo{}

console.log("Bar2.prototype=",Bar2.prototype); //Foo{} 
console.log("Bar2.prototype.constructor=",Bar2.prototype.constructor); //Foo()
console.log("Bar2.prototype.prototype=",Bar2.prototype.prototype); //undefined

console.log("b.__proto__=",b.__proto__); //Foo()
console.log("b.__proto__.__proto__=",b.__proto__.__proto__); //function()
console.log("b.__proto__.__proto__.__proto__=",b.__proto__.__proto__.__proto__); //Object{}
console.log("b.__proto__.__proto__.__proto__.__proto__=",b.__proto__.__proto__.__proto__.__proto__); //null


console.log("b2.__proto__=",b2.__proto__); //Foo{} 
console.log("b2.__proto__.constructor=",b2.__proto__.constructor); //Foo()
console.log("b2.__proto__.__proto__=",b2.__proto__.__proto__); //Foo{}
console.log("b2.__proto__.__proto__.constructor=",b2.__proto__.__proto__.constructor); //Foo()
console.log("b2.__proto__.__proto__.__proto__=",b2.__proto__.__proto__.__proto__); //Object{}
console.log("b2.__proto__.__proto__.__proto__.__proto__=",b2.__proto__.__proto__.__proto__.__proto__); //null

console.log(b2.__proto__ == b2.__proto__.__proto__); //false
console.log(b2.__proto__.constructor == b2.__proto__.__proto__.constructor); //true
console.log(b instanceof Foo); //false
console.log(b2 instanceof Foo); //true
为什么26,28行打印出相同的结果.不解.(firebug中查看26行的Foo{}没有constructor属性,28行的有,但是实质上两者通过.constructor都能得到相同的结果




转载于:https://my.oschina.net/uniquejava/blog/262490

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值