Transferred from: http://www.jianshu.com/p/a81692ad5b5d
typeof obj and obj instanceof Type
In JavaScript, we often use typeof obj and obj instanceof type to identify types, so what is the difference between the two? Take a look at a couple of pieces of code first
<!--the way typeof obj is judged--
<script>
var str = "toby";
console.log(typeof str);// string
var num = 1;
console.log(typeof num);// number
var str2 = new String("toby");
console.log(typeof str2);// object
var num2 = new Number(1);
console.log(typeof num2);// object
</script>
<!--obj1 instanceof Obj2 Way to judge--
<script>
var str = "toby";
console.log(str instanceof String); // false
var num = 1;
console.log(num instanceof Number); // false
var str2 = new String("toby");
console.log(str2 instanceof String); // true
var num2 = new Number(1);
console.log(num2 instanceof Number); // true
</script>
This time is not suspense, directly to the output and conclusions to tell you, from these two pieces of code we can draw a conclusion
typeof obj: A full-lowercase string that returns the type of the Obj object, valid only for the base type, returns an object string if the function is on a reference type, cannot determine the true type of the variable
obj instanceof type: Determines if obj is of type, returns a Boolean, can only function on a reference type, and returns False if it is on the base type.
But we must know the reason why, and we will further explore
The prototype chain in JavaScript
classes in JavaScript
There is no class concept in JavaScript, the creation of objects is done using constructors, or the object is written directly in JSON format {}
<script>
//创建一个Person类,首字母要大写,这个function也是这个类的构造方法
function Person(name, age) {
this.name = name;
this.age = age;
}
var p = new Person("toby", 24);
console.log(p);
</script>
What happened to this new process, let's take a look at the description of the document
When the code new Foo (...) is executed, the following things happen:
A new object is created, inheriting from Foo.prototype.
The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. New Foo is equivalent-to-new Foo (), i.e. if no argument list is specified, and Foo is the called without arguments.
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn ' t explicitly return an object, the object created in step 1 is used instead. (normally constructors don ' t return a value, but they can choose to does so if they want to override the normal object creat Ion process.)
We use the code to describe the new person ("Toby", 24);
//1.方法new的瞬间,得到一个空对象{},它继承自Person.prototype
var p = {};
p.__proto__ = Person.prototype;
//2.方法的this,指向空对象
//3.运行构造方法
{}.name = toby;
{}.age = age;
//4.返回该对象
Person.call(p);
Internal structure in JavaScript objects
1.__PROTO__: This property is a hidden property on a JS object that points to the prototype object of that object's corresponding type.
var p = new Person();
console.log(p.__proto__ == Person.prototype);//true
The object in 2.js is divided into two parts,
Part is the native part, the native part is defined in the constructor, or directly through the object. Property =value assignment;
Part of the extension section, the content of the extension is through the class. Prototype=value assignment;
Two ways to inherit from JavaScript
Common inheritance
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name);
};
//创建一个Student类
function Student(name, age, sn) {
//调用父类的构造方法帮我们初始化属性
Person.apply(this, [name, age]);
this.sn = sn;
}
//复制Person原型中的所有方法
for (var p in Person.prototype) {
Student.prototype[p] = Person.prototype[p];
}
var s = new Student("toby", 24, 1);
s.sayName();
console.log(s instanceof Student);
console.log(s instanceof Object);
console.log(s instanceof Person);
</script>
Again to the happy to do the question Time, according to the conclusion of the beginning, what will the output here? Maybe we think the output is
But after the output was found, the result was
If the second-to-last false may be better understood, and the final false seems to have too much conflict with the inheritance of our notions, then we look at the principle
the principle of instanceof
The principle of obj instanceof type: Along the object's prototype chain, to determine whether a prototype chain has a prototype and type of the same, if found, return true, if it has been found along the prototype chain can not be found, then return false, then we think of this as a formula, Set the formula and walk a wave
console.log(s.__proto__ == Student.prototype);//true
console.log(s.__proto__ == Object.prototype);//false
console.log(s.__proto__.__proto__ == Object.prototype);//true
console.log(s.__proto__ == Person.prototype);//false
console.log(s.__proto__.__proto__ == Person.prototype);//false
So now understand why the first two outputs are true, and the last output is false.
But what if you want the S instanceof person result to be true to reach the requirement that the subclass object can be identified as a parent type instance? Now that we know the principle, it's easy to solve.
Prototype inheritance
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name);
};
function Student(name, age, sn) {
Person.apply(this, [name, age]);
this.sn = sn;
}
for (var p in Person.prototype) {
Student.prototype[p] = Person.prototype[p];
}
//在Student原型中添加Person原型
Student.prototype = Object.create(Person.prototype);
var s = new Student("toby", 24, 1);
console.log(s);
console.log(s instanceof Student);
console.log(s instanceof Object);
console.log(s instanceof Person);
</script>
Is the result of the final output really what we want? We analyze a wave by the formula.
console.log(s.__proto__ == Student.prototype);//true
console.log(s.__proto__ == Object.prototype);//false
console.log(s.__proto__.__proto__ == Object.prototype);//false
console.log(s.__proto__.__proto__.__proto__ == Object.prototype);//true
console.log(s.__proto__ == Person.prototype);//false
console.log(s.__proto__.__proto__ == Person.prototype);//true
From here we know that the result of the output is
Analysis of the prototype chain
So, let's use two graphs to describe the prototype chains in these two types of inheritance.
Diagram The prototype chain in JavaScript