js--call_apply

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>call_apply</title>
    <meta http-equiv="Content-Type" content="text/html; charset=GB2312" />
<meta http-equiv="Content-Type" content="text/html; charset=HZ" />
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
</head>
<script language="javascript">
/*
JavaScrtipt动态变换运行时上下文特性
foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments)==this.foo(arg1, arg2, arg3)
简直是”无中生有”,对象的方法可以任意指派,(有方法的一方,指派给另一方)。call, apply作用就是借用别人的方法来调用,就像调用自己的一样.
*/

function test0(){

    function print(a, b, c){
        alert(a + b + c );
        //alert(a + b + c + d);
        //alert(a + b + c + d+f);
    }

    function example(a, b , c , d){
        alert(arguments); //成功
        alert(this.arguments);//undefined
        
        //用call方式借用print,参数一个一个处理
        //print.call(this, a, b, c, d);
        print.call(this, a, b, b, b);
        
        //用apply方式借用print, 参数作为一个数组传递,
        print.apply(this, arguments);
        //或者封装成数组
        print.apply(this, [a, b, c, d]);
    }
    
    //下面将显示”背光脚本”
    example("背" , "光" , "脚", "本");
    
}

function test1(){

    function Class1(){
        this.showTxt = function(){alert(this.name)}
    }
    
    var obj = new Object();
    obj.name="test1";
    
    Class1.call(obj);   //只是上下文对象发生了变化 也就是扩展了obj对象(使他  凭空多了些调用方法的接口,顺便相似的内容会被覆盖掉)
    
    obj.showTxt();        //test1  是调用函数  如果没有置换掉 就是自身
    alert(obj.name);
    alert(obj.showTxt);//function(){alert(this.name)}  是对象的属性 toString()
    
}


function test2(){
    function Class1(){
        this.name = 'class1';//添加name值
        this.showTxt = function(){alert(this.name)}
    }
    
    function Class2(){
        this.name = 'class2';
    }
    
    var class2 = new Class2();
    Class1.call(class2); //对当前class2对象进行动态的赋值设置处理
    alert("Class2.showTxt........"+Class2.showTxt());   //注意:类实例扩展了接口,但是 类并没有扩展对应的接口************下同***********
    
    
    alert(class2.name); //先定义的 class2 而后有被重置为class1
    class2.showTxt();//class1  对象才能调用方法   
    
    class2.name = 'test1';//重定义obj.name值
    alert(class2.showTxt);//对象的属性 就是字符串 function(){alert(this.name)}
    class2.showTxt();//test1
    
}


function test3(){
    function Class1(){
        this.showTxt = function(){alert(this.name)}
    }
    
    function Class2(){
        this.name = 'class2';
    }
    
    Class1.call(Class2);   //两个类之间的处理
    alert(Class2.showTxt);//对象的属性 也是字符串 function(){alert(this.name)}
    Class2.showTxt();//扩展了类的接口,但是 没有调用类实例化的设置    (注意:类有扩展,类实例没有扩展处理)
    
    class2 = new Class2();        //此时 在创建的对象 已经不具备代理引用的条件了
    alert(class2.showTxt);                //undefined 没有定义属性
    
}

function test4(){

    function Class1(){
        this.showTxt = function(){alert(this.name)};
        this.showTxt2 = function(){alert(this.name)};
    }
    
    function Class2(){
        this.name = 'class2';
    }
    
    var class1 = new Class1();
    var class2 = new Class2();
    
    class1.showTxt.call(class2);//class2类实例上面的方法的调用是  直接的调用,只是上下文this的引用进行了切换而已。
    //class2类实例 及 类 都没有进行扩展
    
    alert("Class2.showTxt........"+Class2.showTxt);//只是 对象方法的调用  类没有扩展
    alert(class2.showTxt);//undefined (同时调用时一次性的,直接调用) ***********************
    alert(class2.showTxt2);//undefined
    
    Class1.call(class2);                //对象的处理
    class2.showTxt();
    class2.showTxt2();
    
}

function test5(){

    function Class1(){
        this.showTxt = function(){alert(this.name)}
    }
    
    function Class2(){
        this.name = 'class2';
    }
    
    var class1 = new Class1();
    class1.showTxt.call(Class2);//类(也是类实例化)上面的方法的调用是  直接的调用,只是上下文this的引用进行了切换而已。
    //Class2类 都没有进行扩展

    alert(Class2.showTxt);        //undefined   
    var class2 = new Class2();  //创建了新的对象 之前的代理引用 已经不成立了
    alert(class2.showTxt);//undefined   
    
}

function test6(){

    function f1(){
        alert(1);
    }
    function f2(){
        alert(2);
    }
    function f3(){
        alert(3);
    }
    function f4(){
        alert(4);
    }
    
    f1.call(f2);//1       //将f1 中的代理this,替换为 f2 ;要创建一个真实的f1的实例化.。。
    f1.call(f3);//1       //将f1 中的代理this,替换为 f2 ;要创建一个真实的f1的实例化.。。

    
    var ff = f1.call;   //自身的创建代理 不去创建对象 并保持这个引用,
    ff.call(f2);//2           //如果单纯的调用,则 创建thisobj的对象
    ff.call(f3);//3
    ff.call(f4)//4
                          
    ff = f4.call;   
    ff.call(f2);//2
    
}

function test7(){

    function jsCall(oThis){//这里的jsCall就是Call
        var argsNew = [];
        alert("arguments.length......"+arguments.length);
        alert(this);
        
        for(var i=1;i<arguments.length;i++){
            argsNew.push(arguments[i]);
        }
        
        alert("before...........");
        return this.apply(oThis,argsNew);
    }
    Function.prototype.jsCall = jsCall;
    /*
        或简写成
    function jsCall(oThis){//这里的jsCall就是Call
        var argsNew = [].slice.call(arguments,1);
        return this.apply(oThis,argsNew);
    }
    */

    //参数已经传递过来,必须通过显示的定义来接收 a,b,c,d,e....
    function f1(a,b){
        alert(["in f1......","kkkkkkkkkkk"]);
        
        //中括号 多个信息的展示处理
        //f1.jsCall(f2)时,没有参数
        alert([this,"it is param="+a+"....."+b,'f1']);
        
        alert("in f1.......end");
    }
    
    function f2(a,b){
        alert("in f2.....");
        alert(this);//?为什么变成了 4321 有知道的话 回复我啊
        alert([this,a+"..."+b,'f2']);
    }
    
    
    //此时处理的 F1的构造函数中的this参数已经发生了 变化
    //f1.jsCall(f2);      //直接调用处理
    //f1.jsCall(f2,1234);// 1234
    //f1.jsCall(f2,1234," after 000");// 1234..... after 000

    
    var ff = f1.jsCall;
    //alert(ff);
    ff.jsCall(f2,4321,"this's really params"," secord param");//4321,this's really params,f2
    
}

</script>    
<body>
应用一对象的一个方法,用另一个对象替换当前对象。
apply([thisObj[,argArray]])
call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

<br/>
<INPUT TYPE=button value="test0" onclick="test0()">
<INPUT TYPE=button value="test1" onclick="test1()">
<INPUT TYPE=button value="test2" onclick="test2()">
<INPUT TYPE=button value="test3" onclick="test3()">
<INPUT TYPE=button value="test4" onclick="test4()">
<INPUT TYPE=button value="test5" onclick="test5()">
<INPUT TYPE=button value="test6" onclick="test6()">
<INPUT TYPE=button value="test7" onclick="test7()">
</body>
</html>

在使用 `npm install` 安装依赖时,可能会遇到多种错误,包括 `node-gyp` 构建失败、Python 语法错误、权限问题(EPERM)以及运行时的 `TypeError` 异常。以下是针对这些问题的具体解决方案: ### 3.1 处理 `node-gyp` 构建失败与 Python 语法错误 `node-gyp` 是用于编译原生 Node.js 模块的工具。在某些情况下,尤其是使用较新版本的 Python(如 Python 3.x)时,`node-gyp` 可能会因语法错误而失败。例如: ``` gyp ERR! stack SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)? ``` 这是由于 `node-gyp` 调用的 Python 脚本仍然使用 Python 2 的语法格式,而当前环境中使用的是 Python 3。解决方法包括: - **使用兼容 Python 2 的环境**:安装 Python 2.7 并将其添加到系统路径中,确保 `node-gyp` 使用的是 Python 2.x 版本。 - **设置 Python 版本**:通过 npm 配置指定 Python 2 的路径: ```bash npm config set python C:\Python27\python.exe ``` - **使用替代模块**:如果项目中依赖 `node-sass` 等需要 `node-gyp` 编译的模块,建议替换为 `sass`(Dart Sass),它是一个纯 JavaScript 实现,无需编译: ```bash npm uninstall node-sass npm install sass ``` 同时,在 Webpack 配置中指定使用 `sass` 作为实现: ```javascript { loader: 'sass-loader', options: { implementation: require('sass') } } ``` ### 3.2 解决 `EPERM` 权限问题 在 Windows 系统中,`npm install` 有时会因权限不足而无法清理 `node_modules` 目录,导致出现 `EPERM` 错误: ``` npm warn cleanup Failed to remove some directories npm warn cleanup [Error: EPERM: operation not permitted, rmdir 'C:\path\to\node_modules\...'] ``` 解决方法包括: - **以管理员权限运行命令**:在 Windows 上,使用管理员权限打开命令提示符或 PowerShell,然后重新执行 `npm install`。 - **手动删除 `node_modules`**:关闭所有终端和编辑器后,手动删除 `node_modules` 文件夹,并重新运行 `npm install`。 - **使用 `rimraf` 删除**:安装 `rimraf` 并使用它来删除顽固的 `node_modules` 文件夹: ```bash npm install -g rimraf rimraf node_modules npm install ``` ### 3.3 处理 `TypeError: Function.prototype.apply was called on undefined` 错误 该错误通常出现在使用某些较新版本的模块时,尤其是在模块依赖链中存在不兼容的版本。例如,在使用 `gitbook` 时,可能会遇到: ``` TypeError: cb.apply is not a function ``` 这通常是因为 `npm` 版本或某些依赖模块版本不兼容导致的。解决方法包括: - **降级 `babel-eslint` 版本**:如果项目依赖 `babel-eslint` 并出现 `token.type.endsWith is not a function` 错误,可尝试降级到兼容版本(如 8.2.2): ```bash npm install babel-eslint@8.2.2 --save-dev ``` - **使用 `--legacy-peer-deps` 安装**:如果依赖冲突导致错误,可尝试使用 `--legacy-peer-deps` 参数跳过 peerDependencies 检查: ```bash npm install --legacy-peer-deps ``` - **检查 `esm.js` 文件**:如果错误提示中指出 `esm.js` 文件存在问题,应检查该文件中是否使用了不兼容的模块加载方式或语法。 ### 3.4 其他常见问题与建议 - **清理 npm 缓存**:有时旧的缓存可能导致安装失败,建议清理缓存并重新安装: ```bash npm cache clean --force rm -rf node_modules package-lock.json npm install ``` - **使用 `nvm` 管理 Node.js 版本**:确保 Node.js 和 npm 版本与项目兼容,避免因版本不匹配导致的错误: ```bash nvm install 16 nvm use 16 ``` - **升级依赖版本**:定期检查并升级项目依赖版本,以减少因依赖弃用或安全漏洞带来的问题。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值