? ? function Person(name, age) {
? ? ? this.name = name;
? ? ? this.age = age;
? ? }
? ? let a1 = new Person("小明", 20);
? ? let a2 = new Person("小菜", 25);
? ? console.log(a1);
打印的对象:
function Person(name, age) {
this.name = name;
this.age = age;
}
function _new(r,...args){
console.log(...args,123456);
// 1.创建一个空对象
let obj={}
// 2.r代表要构造的函数
obj.__proto__=r.prototype
// 3.改变this的指向
const t=r.apply(obj,args)
// 4.判断t的数据类型是一个函数或者是一个对象
const isTrue=t&&typeof t==='function'||typeof t==='object'
// 5.返回创建的空对象
return isTrue?t:obj
}
let a1 = _new (Person,'小明',20 )
let a2 = _new (Person,'小蔡',25 )
console.log(a1);
console.log(a2);
1.首先创建一个空对对象
2.将原始函数的prototype指向新对象的__proto__属性
3.改变this的指向,将this指向新创建的对象,并传入this
4.判断返回值,如果是function或者object就返回
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
console.log("吃苹果");
}
}
let a1 = new Person("小明", 20);
实例化对象的__proto_能够访问构造函数的prototype,因此我们每次new一个新的对象出来,
都能访问到类上挂载的方法,下面我们来证明:
let a1 = new Person("小明", 20);
let a2 = new Person("小蔡", 25);
console.log(a1.__proto__===a2.__proto__); 代码举例子1
打印的结果是true:很明显是一个相同的地址。
console.log(a1.__proto__===Person.prototype);
返回的结果也是true,通过这个例子就很好地解释了prototype的重要性,在prototype对象上放置
方法,没new出一个实例化对象,都使用的是同一快内存的空间,大大节省了内存。
console.log(Person.prototype);
constructor:指回这个类,也就是XXX.prototype? 这个constructor指回来
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat=function(){
console.log('吃苹果');
}
let a1=new Person('小明',20)
console.log(Person.prototype);
这是没用构造器的写法。
方法直接挂载到类的原型上。
将方法挂载到函数的原型上也就是prototype。
告诉我们是从那个类new出来的。
另外一种函数写法:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat=function(){
console.log('吃苹果');
}
// console.log( Person.prototype);
let a1=new Person('小明',20)
console.log(a1);
总而言之,constructor]是指回去,告诉你它是从哪里来的。
?
上图中想表达的是在object这个函数的prototype挂载了很多的方法,根据原型链的查找规则:
任何一个对象都有__proto__,因此Object的原型对象是最后异步,如果找不到就说明没这个方法:
代码:
let obj={}
console.log(obj);
图示:
理解:
在object的原型上挂载了很多的属性方法,也就是最底层,任何一个对象都可以通过__proto__进行访问。