/*
1.javascript中 万物皆对象
2.但是对象是有区别的, 分为普通对象(object)和函数对象(function)
3.规则一: 凡是通过new Function()创建的对象都是函数对象, 其他的都是普通对象
4.Object和Function 都是通过new Function()创造的!
*/
function fn1(){}
var fn2 = function () {}
var fn3 = new Function();
console.log(typeof fn1); // function
console.log(typeof fn2); // function
console.log(typeof fn3); // function
var obj1 = {};
var obj2 = new Object();
var obj3 = new fn1();
var obj4 = new fn3();
console.log(typeof obj1); // object
console.log(typeof obj2); // object
console.log(typeof obj3); // object
console.log(typeof obj4); // object
console.log(typeof Function); // function
console.log(typeof Object); // function
console.log("************************************************")
// 5.在js中, 每当定义一个对象的时候, 对象中都会包含一些预定的属性, 其中函数对象就有一个属性叫prototype
// 6.普通对象没有prototype, 但是有__proto__
// 7.原型对象就是普通对象, 除了Function.prototype
/*
var temp1 = new fn1();
fn1.prototype.name = "张三" temp1.name === "张三"
typeof temp1 ===object ====> fn1.prototype 是 普通对象
var temp2 = new Function();
Function.prototype.name = "小黑" temp2.name === "小黑"
typeof temp2 === function ====> Function.prototype 是 函数对象!
*/
var temp1 = new fn1();
fn1.prototype.name = "张三";
console.log(temp1.name === "张三"); // true
Array.prototype.sayhello= function () {
console.log("张三你好");
}
var arr = new Array();
arr.sayhello(); // 张三你好
console.log(obj1);
console.log(fn1.prototype);
console.log(typeof fn1.prototype);
console.log(typeof Function.prototype);
//8.原型对象的作用: 主要用来做继承
// 问题: 如果构造函数和构造函数的原型对象, 都有同一个方法, 那么会优先继承构造函数的
// 在js底层, 一般都是给父构造函数的原型对象添加方法
var Student = function () {
this.name = "李四";
}
Student.prototype.name = "张三"
var zhangsan = new Student();
console.log(zhangsan.name);
//9.问题: 到底是怎样实现的继承!
// 答案: 靠的是原型链!!!(什么是原型链, 我们等下再讲)
console.log("***************************************");
//10. js在创造对象的时候, 不管是普通对象还是函数对象, 都有__proto__的属性
//11. 规则二: __proto__ 指向创建它的构造函数的原型对象
console.log(zhangsan.__proto__);
console.log(Student.prototype);
console.log(zhangsan.__proto__ === Student.prototype);
//12.构造函数Student.prototype 是谁创造的 Student.prototype是Object创造的
//页就是说, Student.prototype.__proto__ 指向Object.prototype
//我们心里先保留疑问, Student是谁创造 ????
console.log(Student.prototype.__proto__ === Object.prototype);
Object.prototype.age = "18";
console.log(zhangsan.age);
//13.Object.prototype.__proto__ 是 null
console.log(Object.prototype.__proto__ === null);// true
//13.一切归一 大家都是null创造的
console.log(Student.__proto__ === Function.prototype);
console.log(Object.__proto__ === Function.prototype);
console.log(Function.__proto__ === Function.prototype);
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__ === null);// true
//14.道德经曰: 无, 名天地之始, 所以null创造了一切!
console.log("***************************************")
var Animal = function () {
}
var Cat = function () {
}
Animal.jiao = function () {
console.log("喵喵");
}
// Cat.prototype = Animal;
Cat.__proto__ = Animal;
Cat.jiao();
// 15. 规则三: 继承的实现, 其实并不是靠prototype, 而是靠__proto__
// 16.规则四: 原型链的作用, 在于读取对象的某个属性时, js引擎会优先查找对象本身的属性,
// 如果没有, 会去改对象的构造函数的原型对象(prototype)上面找, 如果还是没有,
// 就会去构造函数的原型对象的构造函数的原型对象上寻找, 如果还是找不到, 一直找下去,
// 直到最顶层的原型对象, Object.prototype, 如果还是没有, 则返回undefined!
// 17. 这个过程中, 维持上下层关系的靠的是__proto__
// 题目一:
var HrhArray = function () {
};
var hrhArr = new HrhArray();
hrhArr.__proto__ = new Array();
hrhArr.push(1);
console.log(hrhArr);// [1]
// 题目二:
var obj = {};
var Gouzao = function () {
this.say = function () {
console.log("哈哈");
}
}
obj.__proto__ = new Gouzao();
obj.say();
console.log("******************************************");
//18. 规则五: prototype(原型对象) 有一个属性 叫 constructor
// constructor默认指向prototype(原型对象) 所在的构造函数
function fn5(){
}
console.log(fn5.prototype.constructor === fn5);
//由于constructor属性是定义在prototype上的, 那么就意味着可以被实例对象所继承
var obj5 = new fn5();
console.log(obj5.constructor === fn5);
//可以使用hasOwnProperty 方法来验证一个属性是自己的还是继承过来的
console.log(obj5.hasOwnProperty("constructor"));
//constructor的作用:
//作用一: 分辨原型对象到底属于哪个构造函数
function isInstance(Func, obj){
return obj.constructor === Func;
}
console.log(isInstance(fn5, obj5));
//作用二:可以从一个实例对象新建另一个实例对象
function fn6() {
}
var x = new fn6();
var y = new x.constructor();
// 系统提供一个方法来判断实例对象是否为该构造函数构造----instanceof
console.log(y instanceof fn6);
console.log(isInstance(fn6, y));
//作用三: 在实例方法中, 可以通过constructor调用自身的构造函数
fn6.prototype.createCopy = function () {
return new this.constructor();
};
// this.constructor 指向fn6
var obj6 = new fn6();
console.log(obj6.constructor === fn6)
console.log(obj6.createCopy().__proto__ === fn6.prototype);
//作用四: 继承!!! 非常重要!!!
function Father(){
this.sex = "雄性";
}
function Son(){
this.age = "1";
Son.superclass.constructor.call(this);// 相当于Father.call(this);
}
Son.superclass = new Father();
var chb = new Son();
console.log(chb.age);
console.log(chb.sex);
//由于constructor属性是一种原型对象与构造函数的关联关系
//所以我们在修改原型对象的时候, 务必要小心!
function A(){
}
var a = new A();
console.log(a instanceof A);//true
function B(){
}
A.prototype = B.prototype;
console.log(a.constructor === B)//false
console.log(a.constructor === A)//true
console.log(a instanceof A);//false 结果失真
console.log(a instanceof B);//false 结果失真!
// 谨记 不要直接修改原型对象!
JavaScript中的原型和原型链
最新推荐文章于 2024-09-22 09:45:54 发布