原型、原型链、Function、prototype、constructor

1、函数和对象

基本概念:
1、函数(function)
2、函数对象(function object)
3、本地对象(native object)
4、内置对象(build-in object)
5、宿主对象(host object)

1.1、函数
//函数声明
function foo(){    }

//函数表达式
var foo = function(){  }

// typeof foo  都是function。
1.2、函数对象

在Javascript中,每一个函数实际上都是一个函数对象。
如果我们单纯的把它当成一个函数使用,那么它就是函数。
如果我们通过他来实例化出对象来使用,那么它就可以当成一个函数对象来使用。

function Foo (){}
var foo = new Foo();

typeof foo // object
1.3、本地对象
typeof(Object) // function
typeof(Array) // function
typeof(Date) // function
typeof(RegExp) // function

// Math和Json 以对象方式存在
typeof(Math) // object
typeof(Json) // object
typeof(null) // object


// 如下:
function Object(){

}
function Array(){

}

可以看出,这些本地对象(类)是通过function建立起来的。
Object原本就是一个函数,通过new Object()之后实例化后,创建对象

1.4、内置对象

定义“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。

2、原型

2.1 prototype – 函数的属性

prototype属性是每一个函数都具有的属性,但是不是一个对象都具有的属性。
Javascript里面所有的数据类型都是对象,为了使JavaScript实现面向对象的思想,就必须要能够实现‘继承’使所有的对象连接起来。而如何实现继承呢?JavaScript采用了类似C++,java的方式,通过new的方式来实现实例。

function Foo(){  
}

var foo = new Foo();

foo.__proto__ === Foo.prototype // true

其中Foo中有prototype属性,而foo没有。但是foo中的隐含的proto属性指向Foo.prototype。

2.2 __proto__ 函数和对象都有的属性

__proto__ 属性是每一个对象以及函数都隐含的一个属性。对于每一个含有__proto__属性,他所指向的是创建他的构造函数的prototype。原型链就是通过这个属性构件的

function Foo(){  
}

var foo = new Foo();

foo.__proto__ === Foo.prototype // true

注意!! Object.prototype.__proto__ 指向的是null

// instanceof 一个对象是不是另一个对象 new 出来的
Function instanceof  Object   //true    
Object instanceof  Function  // true
2.2 constructor

原型对象prototype中都有个预定义的constructor属性,用来引用它的函数对象。这是一种循环引用。

function Foo(){};
console.log(Foo.prototype.constructor === Foo); // true
console.log(Foo.__proto__.constructor === Function); // true

3、关系图

Function.__proto__.__proto__  === Object.prototype //true

Object.__proto__  === Function.prototype //true Object也是Function new出来的

upload successful

4、题型(参考关系图更好理解)

手写new的函数过程

例1:
function Fn(){
    this.x = 100;
    this.y = 200;
    this.getX = function () {
        console.log(this.x);
    }
}
Fn.prototype.getX = function () {
    console.log(this.x);
};
Fn.prototype.getY = function () {
    console.log(this.y);
};
var f1 = new Fn;
var f2 = new Fn;
console.log(f1.getX === f2.getX);    //false 自身属性查找,没找到,才找原型上查找
console.log(f1.getY === f2.getY);    //true

console.log(f1.__proto__.getY === Fn.prototype.getY);    //true
console.log(f1.__proto__.getX === f2.getX);        //false
console.log(f1.__proto__.getX === Fn.prototype.getX);    //true
console.log(f1.constructor);    //Fn   f1没有constructor 相当于 (f1.__proto__).constructor === Fn.prototype.constructor
console.log(Fn.prototype.__proto__.constructor);    //Object
f1.getX();    //100    this=>f1
f1.__proto__.getX();    //undefined     this=>f1.__proto__(Fn.prototype)
f2.getY();    //******  200    this=>f2
Fn.prototype.getY();    //undefined    this=>f2.__proto__(Fn.prototype)

//输出结果: false,true,true,false,true,Fn,Object,100,undefined,200,undefined
例2:
function fun(){
    this.a = 0;
    this.b = function(){
        console.log(this.a);
    }
}
fun.prototype = {
    b: function(){
        this.a = 20;
        console.log(this.a);
    },
    c: function(){
        this.a = 30;
        console.log(this.a);
    }
}
var my_fun = new fun();
my_fun.b();    //0  私有方法     this=>my_fun
console.log(my_fun.a); // 0
my_fun.c();    //30 公有方法    this=>my_fun this.a = 30(将私有属性a修改为30)
console.log(my_fun.a); // 已经修改为30
var my_fun2 = new fun();
console.log(my_fun2.a); // 0 my_fun2重新构造了的
my_fun2.__proto__.c();    // 30  fun.prototype this=>my_fun2.__proto__ 当前实例通过原型链在类的共有属性上增加了一个a:30
console.log(my_fun2.a); // 0 不变
console.log(my_fun2.__proto__.a);  //30  c()给原型链赋值 30   
例3:
function a(){
}
function b(){
}
var b1 = new b();
a.prototype = b1;
var a1 = new a();
console.log(a1.__proto__.__proto__===b.prototype) //true
console.log(a1.__proto__.__proto__===b.prototype.__proto__) // false
console.log(a1.__proto__.__proto__.__proto__ === Object.prototype) // true
console.log(a1.__proto__.__proto__.__proto__.__proto__ )  //  null

console.log(a1.__proto__.constructor ===  b)  //true  a1.__proto__等于a.prototype   上面赋值为b1。 相当于b1.constructor === b
console.log(a1.__proto__.__proto__.constructor ===b) // true
console.log(a1.__proto__.constructor ===  a1.__proto__.__proto__.constructor) // 会如果没找到该属性默认调用__proto__ 去查找

console.log(a1.__proto__.__proto__.__proto__ === Object.prototype) // true 函数原型的__proto__ 最终都指向了 Object.prototype
console.log(a1.__proto__.__proto__.constructor.__proto__ === Function.prototype) // true 构造函数的__proto__ 最终都指向了 Function.prototype

本篇
原型、原型链、Function、prototype、constructor 原型、原型链、Function、prototype、constructor
1、函数和对象基本概念:1、函数(function)2、函数对象(function object)3、本地对象(native object)4、内置对象(build-in object)5、宿主对象(host object) 1.1、函数/
2021-12-09
下一篇
JS中encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent() JS中encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()
1、东西比较基础,只是做个总结说明 1.encodeURI(),和encodeURIComponent()是对字符-进行编码。2.decodeURI(),和decodeURIComponent()是对相应编码过的字符-进行解码。 使用场景