zoukankan      html  css  js  c++  java
  • javascript面向对象--上下文调用模型

    上下文调用方式是面向对象中比较复杂的一种应该方式,摆脱了传统的this的限制。下面是一些介绍,也会引申一些数组的操作方式来解释上下文调用的方式。

    一、上下文 就是环境, 就是自定义设置 this 的含义 
    
    语法:
    1. 函数名.apply( 对象, [ 参数 ] );
    2. 函数名.call( 对象, 参数 );
    
    描述:
    1. 函数名就是表示的函数本身, 使用函数进行调用的时候默认 this 是全局变量
    2. 函数名也可以是方法提供, 使用方法调用的时候, this 是指当前对象.
    3. 使用 apply 进行调用后, 无论是函数, 还是方法都无效了. 我们的 this, 由 apply 的第一个参数决定
    
    注意: 
    1. 如果函数或方法中没有 this 的操作, 那么无论什么调用其实都一样.
    2. 如果是函数调用 foo(), 那么有点像 foo.apply( window ).
    3. 如果是方法调用 o.method(), 那么有点像 o.method.apply( o ).
    二、参数问题
    无论是 call 还是 apply 在没有后面的参数的情况下( 函数无参数, 方法无参数 ) 是完全一样的.
    ```
    	function foo() {
    		console.log( this );
    	}
    	foo.apply( obj );
    	foo.call( obj );
    ```
    
    第一个参数的使用也是有规则的
    1. 如果传入的是一个对象, 那么就相当于设置该函数中的 this 为参数
    2. 如果不传入参数, 或传入 null. undefiend 等, 那么相当于 this 默认为 window
    ```
    	foo();
    	foo.apply();
    	foo.apply( null );
    	foo.call( undefined );
    ```
    3. 如果传入的是基本类型, 那么 this 就是基本类型对应的包装类型的引用
    	* number -> Number
    	* boolean -> Boolean
    	* string -> String
    
    4.在使用 上下文调用的 时候, 原函数(方法)可能会带有参数, 那么这个参数在上下文调用中使用 第二个( 第 n 个 )参数来表示 
    ``` function foo( num ) { console.log( num ); } foo.apply( null, [ 123 ] ); // 等价于 foo( 123 ); ```
    三、数组案列
    将伪数组转换为数组
    
    传统的做法
    ```
    	var a = {};
    	a[ 0 ] = 'a'; 
    	a[ 1 ] = 'b';
    	a.length = 2;
    	
    	// 数组自带的方法 concat
    	// 语法: arr.concat( 1, 2, 3, [ 4, [ 5 ] ] );
    	// 特点不修改原数组
    	var arr = [];
    	var newArr = arr.concat( a );
    ```
    
    由于 a 是伪数组, 只是长得像数组. 所以这里不行, 但是 apply 方法有一个特性, 可以将数组或伪数组作为参数
    ```
    	foo.apply( obj, 伪数组 ); // IE8 不支持
    ```
    
    将 a 作为 apply 的第二个参数
    ```
    	var newArr = Array.prototype.concat.apply( [], a )
    ```
    
    处理数组转换, 实际上就是将元素一个一个的取出来构成一个新数组, 凡是涉及到该操作的方法理论上都可以
    1. push, unshift
    2. slice
    3. splice
    
    push 方法
    
    ```
    	用法:  arr.push( 1 ); 将这个元素加到数组中, 并返回所加元素的个数
    		  arr.push( 1, 2, 3 ); 将这三个元素依次加到数组中, 返回所加个数
    	
    	var a = { length: 0 }; // 伪数组
    	a[ a.length++ ] = 'abc'; // a[ 0 ] = 'abc'; a.length++;
    	a[ a.length++ ] = 'def';
    	
    	// 使用一个空数组, 将元素一个个放到数组中即可
    	var arr = [];
    	arr.push( a ); // 此时不会将元素展开, 而是将这个伪数组作为一个元素加到数组中
    	// 再次利用 apply 可以展开伪数组的特征
    	arr.push.apply( arr, a );
    	// 利用 apply 可以展开伪数组的特性, 这里就相当于 arr.push( a[0], a[1] )
    ```
    
    slice
    
    ```
    	语法: arr.slice( index, endIndex )
    	如果第二个参数不传, 那么就是 从 index 一致获取到结尾
    	该方法不会修改原数组
    	
    	var a = { length: 0 };
    	a[ a.length++ ] = 'abc';
    	a[ a.length++ ] = 'def';
    	
    	// 假设他是一个数组, 就是应该 从 0 项开始截取到 最后
    	// 如果可以的话, 应该 a.slice( 0 )
    	// 但是他没有该方法
    	// 借用 数组的 slice, 将 this 转换成 这个伪数组
    	
    	var arr = [];
    	var newArr = arr.slice.apply( a, [ 0 ] );
    ```
    
    
    求数组中的最大值
    
    传统
    ```
    	var max = arr[ 0 ];
    	for ( var i = 1; i < arr.length; i++ ) {
    		if ( arr[ i ] > max ) {
    			...
    		}
    	}
    ```
    
    在 js 中的 Math 对象中提供了很多数学函数. Math.max( 1,2,3 )
    
    还是利用 apply 可以展开数组的特性
    ```
    	var arr = [ 123456,12345,1234,345345,234,5 ];
    	Math.max.apply( null, arr );
    ```

  • 相关阅读:
    ELF 格式简介
    gdb 使用说明;ARM 汇编
    博士研究生的组会PPT汇报相关-labgirls
    浅尝辄止·认识Blazor及基础使用
    VBA·Function的基础使用
    WCF·无法自动进入并单步执行服务器。调试器未能在服务器进程中停止。
    Word·查找任意汉字的方法
    VBA·编译错误:ByRef参数类型不符
    排坑·QQ浏览器打开MD文件时显示下载不能直接打开
    MSSQL·PIVOT关键字实现列转行
  • 原文地址:https://www.cnblogs.com/ruose/p/5759143.html
Copyright © 2011-2022 走看看