/*
Function.prototype;//function() {}
Object.prototype;//Object {}
Number.prototype;//Number {[[PrimitiveValue]]: 0}
Boolean.prototype;//Boolean {[[PrimitiveValue]]: false}
Array.prototype;//[]
String.prototype;//String {length: 0, [[PrimitiveValue]]: “”}
*/
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);
console.log(typeof fn2);
console.log(typeof fn3);
var obj1 = {};
var obj2 = new Object();
var obj3 = new fn1();
var obj4 = new fn3();
// 以下都是普通对象
console.log(typeof obj1);
console.log(typeof obj2);
console.log(typeof obj3);
console.log(typeof obj4);
//以下开头首字母是大写, 并不带括号 皆是函数对象
console.log(typeof Function);
console.log(typeof Object);
/*
5.在js中,每当定义一个对象的时候,对象中都会包含一些预定的属性,其中函数对象就有一个属性叫prototype
6.普通对象没有prototype 但是有__proto__
7.原型对象就是普通对象,除了Function.prototype
*/
var temp1 = new fn1();
fn1.prototype.name = '老黄';
console.log(temp1.name);
console.log(temp1.name === '老黄');
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);
console.log(typeof Object.prototype);
/*
8.原型对象的作用:主要用来做继承
问题:如果构造函数和构造函数的原型对象,都有同一个方法,那么会优先继承构造函数的?
在js底层,一般都是给父构造函数的原型对象添加方法
*/
var Student = function(){
this.name = '老黄',
this.wife = '老黄的老婆'
}
Student.prototype.wife = '某某某';
var mou = new Student();
console.log(mou.name + ' ' + mou.wife);
/*
9.问题:到底是怎样实现的继承?
靠的是原型链
10.js在创造对象的时候,不管是普通对象还是函数对象,都有__proto__的属性
11.规则二:__proto__ 指向创建他的构造函数的原型对象
*/
console.log(mou.__proto__);
console.log(Student.prototype);
console.log(mou.__proto__ === Student.prototype); //true
/*
12.构造函数Student.prototype 是谁创造的 Student.prototype是object创造的
也就是说, Student.prototype.__proto__ 指向Object.prototype
*/
console.log(Student.prototype.__proto__ === Object.prototype); //true
Object.prototype.age = '66';
console.log(mou.age);
/*
13.Object.prototype.__proto__ 指向是null 无中生有
一切归一,都是由null创造的
*/
console.log(Student.__proto__ === Function.prototype); //true
console.log(Object.__proto__ === Function.prototype); //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__ === null); //true
/*
14.道德经曰: 无,名天地之始 所以null创造了一切
*/
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__
*/
/*
18.规则五:prototype(原型对象) 有一个属性 constructor
constructor 默认指向prototype 所在的构造函数
*/
function fn5(){
}
console.log(fn5.prototype.constructor === fn5);
//由于constructor 属性时定义在prototype上的.意味着可以被实例对象所继承
var obj5 = new fn5();
console.log(obj5.constructor === fn5);
//可以使用hasOwnPrototype 方法验证一个属性是否是自己的还是继承过来的
// 作用一:分辨原型对象到底属于哪个构造函数
function isInstanceof(Func,obj){
return obj.constructor === Func;
}
console.log(isInstanceof(fn5,obj5));
// 作用二:可以从一个实例对象重新建立一个实例对象
function fn6(){
};
var x = new fn6();
var y = new x.constructor();
//系统提供一个方法来判断实例对象是否为该构造函数构造 --instanceof
console.log(y instanceof fn6);
console.log(isInstanceof(fn6,y));
// 作用三: 在实例方法中,可以通过constructor调用自身的构造函数
fn6.prototype.creatCopy = function(){
return new this.constructor;
}
// this.constructor 指向fn6
var obj6 = new fn6;
console.log(obj6.constructor === fn6);
console.log(obj6.creatCopy().__proto__ === fn6.prototype);
// 所以this指向obj6
// 作用四: 继承 .(非常重要!!)
function father(){
this.sex = '男'
// this.age = '55';
}
function son(){
this.age = '1';
// son.superclass.constructor 父亲创建的实例 相当于father
son.superclass.constructor.call(this);
// this指向son的实例对象就是father
}
son.superclass = new father();
var xxx = new son();
console.log(xxx.age);
console.log(xxx.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