# 原型对象 prototype

每一个对象都有一个原型对象

function Test(){

}
Test.prototype.name="原型对象";
Test.prototype.showName = function(){
alert(showName);
}
1
2
3
4
5
6
7

# 对象的原型链

# 眼前

  1. 只要是对象就有原型
  2. 原型也是对象
  3. 只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象,那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列,这个结构就被成为原型链
  4. 原型链到哪里是一个头?
  5. 一个默认的原型链结构是什么样子的?
  6. 原型链结构对已知语法结构有什么修正?

# 原型链的结构

  1. 原型链继承就是利用就是修改原型链结构( 增加、删除、修改节点中的成员 ), 从而让实例对象可以使用整个原型链中的所有成员( 属性和方法 )
  2. 使用原型链继承必须满足属性搜索原则

# 属性搜索原则

  1. 所谓的属性搜索原则, 就是对象在访问属性与方法的时候, 首先在当前对象中查找
  2. 如果当前对象中存储在属性或方法, 停止查找, 直接使用该属性与方法
  3. 如果对象没有改成员, 那么再其原型对象中查找
  4. 如果原型对象含有该成员, 那么停止查找, 直接使用
  5. 如果原型还没有, 就到原型的原型中查找
  6. 如此往复, 直到直到 Object.prototype 还没有, 那么就返回 undefind.
  7. 如果是调用方法就包错, 该 xxxx 不是一个函数

# 原型链结构图

  1. 构造函数,对象原型链结构图

    function Person (){
        
    };
    var p = new Person();
    
    1
    2
    3
    4
  2. {} 对象原型链结构图

  3. [] 数组原型链结构图

  4. Object.prototype 对应的构造函数

  5. div 对应的构造函数

  6. div -> DivTag.prototype( 就是 o ) -> Object.prototype -> null

    var o = {
        appendTo: function ( dom ) {
        }
    };
    function DivTag() {}
    DivTag.prototype = o;
    
    var div = new DivTag();
    
    1
    2
    3
    4
    5
    6
    7
    8

# 函数的构造函数 Function

new Function( arg0, arg1, arg2, ..., argN, body );
1
  1. Function 中的参数全部是字符串
  2. 该构造函数的作用是将 参数链接起来组成函数
  • 如果参数只有一个, 那么表示函数体
  • 如果参数有多个, 那么最后一个参数表示新函数体, 前面的所有参数表示新函数的参数
  • 如果没有参数, 表示创建一个空函数

# 创建一个打印一句话的函数

// 传统的
function foo () {
    console.log( '你好' );
}
// Function
var func = new Function( 'console.log( "你好" );' );
// 功能上, 这里 foo 与 func 等价
1
2
3
4
5
6
7

# 创建一个空函数

// 传统
function foo () {}
// Function
var func = new Function();
1
2
3
4

# 传入函数内一个数字, 打印该数字

// 传统
function foo ( num ) {
    console.log( num );
}
// Function
var func = new Function ( "num" ,"console.log( num );" );
func();
1
2
3
4
5
6
7

# 利用 Function 创建一个函数, 要求传入两个数字, 打印其和

var func = new Function( 'num1', 'num2', 'console.log( num1 + num2 );' );
1

练习: 利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.

练习: 利用 Function 创建一个求三个数中最大数的函数.

// 传统
function foo ( a, b, c ) {
    var res = a > b ? a : b;
    res = res > c ? res : c;
    return res;
}
// Function
var func = new Function( 'a', 'b', 'c', 'var res = a > b ? a : b;res = res > c ? res : c;return res;' )
1
2
3
4
5
6
7
8

# 解决代码太长的办法:

  1. 利用 加法 连接字符串

    var func = new Function( 'a', 'b', 'c',
         'var res = a > b ? a : b;' +
         'res = res > c ? res : c;' +
         'return res;' );
    
    1
    2
    3
    4
  2. 利用字符串特性

    function foo ( a, b, c ) {
        var res = a > b ? a : b;
        res = res > c ? res : c;
        return res;
    }
    var func = new Function( 'a', 'b', 'c', 'return foo( a, b, c );' );
    
    1
    2
    3
    4
    5
    6

# arguments 对象

arguments 是一个伪数组对象. 它表示在函数调用的过程中传入的所有参数的集合.

在函数调用过程中没有规定参数的个数与类型, 因此函数调用就具有灵活的特性, 那么为了方便使用

在每一个函数调用的过程中, 函数代码体内有一个默认的对象 arguments,它存储着实际传入的所有参数.

js 中函数并没有规定必须如何传参

  1. 定义函数的时候不写参数, 一样可以调用时传递参数
  2. 定义的时候写了参数, 调用的时候可以不传参
  3. 定义的时候写了一参数, 调用的时候可以随意的传递多个而参数

在代码设计中, 如果需要函数带有任意个参数的时候, 一般就不带任何参数, 所有的 参数利用 arguments 来获取.

一般的函数定义语法, 可以写成:

function foo ( /* ... */ ) {

}
1
2
3

利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.

function foo ( ) {
    // 所有的参数都在 arguments 中. 将其当做数组使用
    // 问题而已转换成在有一个数组中求最大值
    var args = arguments;
    var max = args[ 0 ];
    for ( var i = 1; i < args.length; i++ ) {
        if ( max < args[ i ] ) {
            max = args[ i ];
        }
    }
    return max;
}
1
2
3
4
5
6
7
8
9
10
11
12

练习: 利用 Function 写一个函数, 要求传入任意个数字 求和

# 函数的原型链结构

任意的一个函数, 都是相当于 Function 的实例. 类似于 {} 与 new Object() 的关系

function foo () {};
// 告诉解释器, 有一个对象叫 foo, 它是一个函数
// 相当于 new Function() 得到一个 函数对象
1
2
3
  1. 函数有 __proto__ 属性
  2. 函数的构造函数是 Function
  3. 函数应该继承自 Function.prototype
  4. Fucntion.prototype 继承自 Object.protoype
  5. 构造函数有prototype, 实例对象才有__proto__指向原型, 构造函数的原型才有 constructor 指向构造函数

# intanceof

array instanceof Array

判断 构造函数 Array 的原型 是否在 实例对象 array 的原型链存在

最近更新: 2019/10/17 上午4:20:42