昨天看一场公开课,讲述的是关于js原型方面的。处于懵逼状态,现在还是,,,故在此一边整理一边再好好回顾一下。如果有所出入,望指正。
先拿昨天晚上的三个面试题,如果你没问题,大佬,你可以走了
怎么样,蒙蔽了吧。js无形装逼,一直装逼一直爽,苦了前端娃
还有如下操作,秀了吧,也是第一次见
var sum = new Function('a', 'b', 'return a + b');
console.log(sum(2, 6)); //8
一、普通对象与函数对象
JavaScript 中 万物皆对象 ! 但对象也是有区别的,分为普通对象和函数对象。Object Function是JS自带的函数对象。
console.log(typeof Object) // function
console.log(typeof Function) // function
function f1(){}
var f2 = function(){}
var f3 = new Function('str','console.log(str)')
console.log(typeof f1) //function
console.log(typeof f2) //function
console.log(typeof f3) //function
var o1 = {}
var o2 = new Object()
var o3 = new f1()
function f1(){}
console.log(typeof o1) //object
console.log(typeof o2) //object
console.log(typeof o3) //object
在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。怎么区分,其实很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
二、构造函数
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() { alert(this.name) }
}
var person1 = new Person('Jact', 21, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');
上面的例子中 person1 和 person2 都是 Person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。
console.log(person1.__proto__.constructor == Person); //true
console.log(person2.__proto__.constructor == Person); //true
person1 和 person2 都是 构造函数 Person 的实例
实例的构造函数属性(constructor)指向构造函数。
三、原型对象
在 JavaScript 中,每当定义一个对象(万物皆对象)的时候,对象中都会包含一些预定的属性。其中每个函数对象都有一个prototype属性,这个属性指向函数的原型对象。
function Person() {}
Person.prototype.name = 'Jack';
Person.prototype.age = 18;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function() {
alert(this.name);
}
var person1 = new Person();
person1.sayName(); // 'Jack'
var person2 = new Person();
person2.sayName(); // 'Jack'
console.log(person1.sayName == person2.sayName); //true
每个对象都有 proto 属性,但只有函数对象才有 prototype 属性
__proto__隐性原型对象,指向其构造函数的prototype
console.log(person1.__proto__ === Person.prototype); //true
如上图描述的,Person有prototype属性, person1没有。
原型对象就是 Person.prototype
由上文可以看出
person1.constructor == Person // person1.__proto__constructor == Person
Person.prototype.constructor == Person
person1 为什么有 constructor 属性?那是因为 person1 是 Person 的实例。
那 Person.prototype 为什么有 constructor 属性??同理, Person.prototype (你把它想象成 A) 也是Person 的实例。
也就是在 Person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype,基本过程如下:
var A = new Person();
Person.prototype = A;
原型对象(Person.prototype)是 构造函数(Person)的一个实例。
最好的话,还是自己弄几行代码,自己看看吧
四、 _ proto _
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1 有一个 __proto__属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:
Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;
五、原型链
在我之前 文章 提到,有兴趣的可以看下
原型链的尽头是null,隐性原型
第一题的答案
obj.__proto__.constructor.name
其他自己打印吧,我才不会跟你说,我也有点糊 , , , , , ,
person1.__proto__ 是什么?
Person.__proto__ 是什么?
Person.prototype.__proto__ 是什么?
Object.__proto__ 是什么?
Object.prototype__proto__ 是什么?