补充原型题目
第四题
function Person(){
// __proto__这个属性记录person1的原始模型
/*
this -->{
__proto__:Person.prototype;
}
return this
*/
};//工厂
Person.prototype.name = "huasheng";//原始模型
/*Person.prototype = {(1)给原始模型设置name属性
name : "huasheng", --> name:"小明",
}
Person.prototype = {(2)
name: "oldsix",
}
*/
var person1 = new Person();//出厂
Person.prototype = {
name:"oldsix",
}
person1.__proto__.name = "小明";//修改 new Person()启动的构造函数
// name = "huashneg" -- > name = "小明"
console.log(Person.prototype.name);//打印oldsix
第五题
function Person(){
/* __proto__这个属性记录person1的原始模型
this-->{
__proto__:Person.prototype;
}return this
*/
};
Person.prototype = {
name:"oldsix",
};
/*
Person.prototype = {(1)
name:"oldsix" -- > name:"huasheng" --> name = "小明"
}
*/
var person1 = new Person();
Person.prototype.name = "hausheng";//修改Person.prototype的name属性
person1.__proto__.name = "小明";//修改Person.prototype的name属性
console.log(Person.prototype.name);
第六题
function Person(){
/*人为打乱__proto__的指向不让你指向原始模型,认你指向任何一个对象
this-->{
__proto__:Person.prototype;(1)
__proto__:{
name:"我把你的指向给搞乱了"
}
}return this
*/
};
/*
Person.prototype = {(1)
name:"oldsix",
}
*/
Person.prototype = {
name:"oldsix",
}
var person1 = new Person();
person1.__proto__ = {
name:"我把你的指向给搞乱了",
}//通过这种方式可以人为打乱__proto__的原始模型指向的
console.log(person1.name);
第七题
function Person(){
/*
this -->{
__proto__:Person.prototype;
-->__proto__:Person.prototype.name = "xiaoming";(人为修改了原始模型)
}return this
*/
};
Person.prototype.name = "hausheng";
/*
Person.prototype = {(1)
name:"huasheng", --> name:"xiaoming",
}
*/
var person1 = new Person();
person1.__proto__.name = "xiaoming";
console.log(Person.prototype.name);//"xiaoming"
第八题
function Person(){
/*
this-->{
__proto__:Person.prototype;
__proto__:{//修改了person1上的原始模型
name: 'xiaoming',
}
} return this
*/
};
Person.prototype.name = 'huasheng';
/*
Person.prototype = {(1)
name:"huasheng",
}
Person.prototype = {(2)
name:"oldsix",
}
*/
var person1 = new Person();
Person.prototype = {
name: 'oldsix'
}
person1.__proto__ = {
name: 'xiaoming'
}
console.log(person1.name);//打印xiaoming
原型链
只要是对象就会有__proto__
属性 指向对象的原型(爸爸)
如果想知道一个属性的原始模型是谁那么可以直接用__proto__
这个属性
function Person(){}
Person.prototype = {
name:"huasheng",
}
var person1 = new Person();
console.log(person1.__proto__)//打印person1的原型
person1
的原型就是{name:"huasheng"}
这个对象
我想看一下Person
的初始的原始模型长什么样
function Person(){};
console.log(Person.prototype);//查看原始模型的初始样子
那Person.prototype.constructor===Person
吗??
function Person(){};
console.log(Person.prototype.constructor===Person);
结果是全等的是true
那么可不可以把constructor
的原始模型的构造函数的构造函数给人为的修改呢吗??
function Person() { }
Person.prototype = {
name: "huasheng",
}
var person1 = new Person();
console.log(Person.prototype.constructor = Number);
//修改construction的构造函数也能改原始值但是没有任何意义
Person.prototype
原型
- 初始存在
constructor
这个属性,该属性记录了原始模型的构造函数(所在工厂) - 还存储了
__proto__
属性
普通函数和构造函数没有任何的区别,只要一个函数前面加上new
启动了这个函数,那么这个函数就是构造函数(每一个函数都有做构造函数的潜质)
那么通过new
关键词,实例化的函数有没有constructor
这个属性
function Person(){
/*
this-->{
__proto__:Person.prototype;
}return this
*/
};
var person1 = new Person();
console.log(person1.constructor);
那么所有对象的最终点是什么
function Person(){};
var person1 = new Person();
console.log(Person.prototype.__proto__);
如果一个对象上没有__proto__
属性的话他就是Object.prototype
function Person(){};
var person1 = new Person();
console.log(Person.prototype.__proto__===Object.prototype);
是true
表示完全相等
person1
他是是个产品,那么这个产品的模子是Person.prototype
,那么这个产品的模子的模子是Object.prototype
,Object
是JS内置的构造函数他可以构造一个对象。Object.prototype
是所有对象的最终点是没有__proto__
属性的。
以下代码的输出结果是什么
function Grand(){
/*
this-->{
__proto__:Grand.prototype;
} return this
*/
};
Grand.prototype.sex = "male";
/*
Grand.prototype = {
sex = "male",
__proto__:Object.prototype 原型链的终端
}
*/
var grand = new Grand();
function Father(){
this.age = 50;
/*
this-->{
__proto__:Father.prototype,
} return this
*/
}
Father.prototype = grand;
/*
Father.prototype = {
sex = "male",
}
*/
var father = new Father();
function Son(){
this.name = "huasheng";
/*
this-->{
__porto__:Son.prototype;
}return this
*/
}
Son.prototype = father;
/*
Son.prototype = {
age = 50,
}
*/
var son = new Son();
console.log(son.name);//从自身上自动name = "huasheng"
console.log(son.age);//从Father身上找到 age = 50
console.log(son.sex);//从Grand身上找到 sex = "male"
那么Object.prototype 原型链的终端
有没有toString()
这个函数呢
console.log(son.toString)
son
上是有toString
的,他是个函数,他会顺着原型链查找如果有就打印出来,如果在原型链上都没有找到就返回undefined
原型链的终端的原始模型是什么???
console.log(Object.prototype.__proto__);
console.log(Object.prototype.__proto__===null);
原型链的终端的原始模型是null
Object.prototype.__proto__===null
判断结果是全等的是true
在对象上查找属性的步骤(原型链查找步骤)
- 先从自身查找属性,如果自身没有找到这个属性,那就从自身的
__proto__
上查找, - 如果还是没有找到这个属性,那就继续往沿着
__proto__
上查找,我们把这种查找规则称为原型链查找, - 如果在
Object.prototype
(原型链终端)上没有找到指定属性 则结果是undefined
- 把由
__proto__
组成的链式结构称为原型链
hasOwnProperty
和 instanceof
属性
属性可以分两种:
- 自身属性(自己身上本来就有的属性叫自身属性)
- 原型链上面的属性(自己身上没有,通过原型链的方法查找到了就叫做原型链上面的属性)
obj.hasOwnProperty("属性名")
obj.hasOwnProperty("属性名")
判断属性是否是自身属性- 如果是自身属性 就返回
true
- 如果不是自身属性 就返回
false
function Person(){
this.name = "hausheng";
this.age = 28;
}
Person.prototype.sex = "male";
var person1 = new Person();
console.log(person1.hasOwnProperty("name"));
console.log(person1.hasOwnProperty("sex"));
A instanceof B
(instanceof
)他是一个操作符
A instanceof B
判断对象A的原型链上有没有构造函数B的原型
function Person(){
this.name = "hausheng";
this.age = 28;
}
Person.prototype.sex = "male";
var person1 = new Person();
console.log(person1 instanceof Person);
//instanceof 前面的参数是一个对象,后面的参数是构造函数
那么person1
的原型链上没有用构造函数Object
呢??
console.log(person1 instanceof Object);
person1
对象上面的原型链是有Object
的,是因为Object.prototype
是所有对象的终端是对象就有终端,是原型链上面的终端都是Object.prototype
JS中所有对象中的原型链上的终端都是Object.prototype
JS中内置的构造函数
Number
构造数字对象String
构造字符串对象Boolean
构造布尔对象Object
构造对象Function
构造函数对象RegExp
构造正则对象Math
构造数学对象Date
构造时间对象
一般情况下都喜欢用字面量形式声明一个数据var a = 2
方便简洁,如果通过构造函数的形式构造了一个数据var num = Number(2)
这做的的话很麻烦,除非想要用构造函数构造自定的功能方法时要使用构造函数。
var num = new Number(2);
console.log(num instanceof Object);
var str = new String("huasheng");
console.log(str instanceof Object);
var bool = new Boolean(false);
console.log(bool instanceof Object);
var obj = new Object;
console.log(obj instanceof Object);
var fn = new Function;
console.log(fn instanceof Object);
var reg = new RegExp(/2/);
console.log(reg instanceof Object);
var math = Math;
console.log(math instanceof Object);
var date = new Date(2019,5,25,7);
console.log(date instanceof Object)
结论instanceof
前面写的一个对象,后面写的是一个Object
,那么返回值一定是true
in
操作符
我希望不管是自身属性和原型链上面的属性都返回的是true
那该怎么办??
function Person() {
this.name = 'heaven';
this.age = 28;
}
Person.prototype.sex = 'male';
var person1 = new Person();
console.log("sex" in person1);
in
操作符,是不管你是自身属性还是原型链上面的属性返回还的结果都是true
,只要是能从person1
找到sex
这个属性那么返回会来的结果就是true
补充for in
循环
function Person() {
this.name = 'heaven';
this.age = 28;
}
Person.prototype.sex = 'male';
var person1 = new Person();
for(key in person1){//遍历对象 for in 循环 可以遍历到原型链上的属性
console.log(key);
}
for in
循环是遍历对象用的,及其原理就是他的in
关键词他可以顺着对象中的__proto__
这个属性去找要遍历的对象,只要你的对象在要遍历原型链上他都能遍历到
所有的对象的原型链终端都是Object.prototype
??
Object.create(原型)
用自己定义原型来创建对象
var obj = Object.create({
//这个属性可以人为的填写一些对象作为原始模型的
name:"huasheng",
})
console.log(obj);
console.log(obj.__proto__);
create
这个函数执行的时候,可以传递一个对象作为原始模型,这个函数的结果是一个新的对象,新的对象的原始模型就是在create
函数中传递的对象
var person = {
name: "huasheng",
}
var obj = Object.create(person)
console.log(obj.__proto__=== person);
查询obj
的原始模型和person
做全等比较是true
,表示自己定义的create
属性和obj
的原始模型是一致的,就是用create
属性指定自己的原始模型
create
这个函数不仅仅可以传一个对象,还有可以传null
var obj = Object.create(null)
console.log(obj);
No properties
表示没有属性,就是没有原型
var obj = Object.create(null)
console.log(obj instanceof Object);
现在obj
是一个对象,本来obj
这个变量中就没有原型,那他怎么用Object
找到原型链的终端呢结果就是false
并不是所有的对象的原型链终端都是Object.prototype
,在用create
函数定义并且括号里的值是null
他的原型链终端就不是Object.prototype
Object.create(null)
这个对象的原型链终端不是Object.prototype