JavaScript

JavaScript - 严格模式 - 作用域

2017-03-29  本文已影响117人  西巴撸

今天先从一个小案例说起,面向对象的内容已经过去一半,剩下的内容也至关重要 ! 希望帮到你的朋友, 能持续关注更新 !

需求 : 图书管理操作

var list = [
        {name:"专业主义",author:"大前研一"},
        {name:"红楼梦",author:"曹公子"},
        {name:"什么是批判",author:"福柯"},
        {name:"十万个为什么?",author:"作者不详"}
    ];
    //01 提供构造函数
    function BookListManager(){
        this.bookList = null;
    }

    //02 设置原型对象
    BookListManager.prototype = {
        init:function(arrayList){
            this.bookList = arrayList || [];
        },
        getBookByName:function (name) {
        //01 能够找到该对象,返回
        for (var i = 0; i < this.bookList.length; i++)
        {
            var obj = this.bookList[i];
            if (obj.name == name)
            {
                return obj;
            }
        }

        //02 找不到这个对象,返回null
        return null;
    },
        addBook:function (bookObj){
        this.bookList.push(bookObj);
    },
        updateBook:function (name,author){
        var book = this.getBookByName(name);   //在原型方法中要调用其它的原型方法需要使用this
        book.author = author;
    },
        removeBook:function (name){
        var book = this.getBookByName(name);
        var index = this.bookList.indexOf(book); //返回指定对象的索引,如果没有那么就返回-1
        if(index == -1)
        {
            throw "要删除的数据不存在!";
        }
        //删除对象
        this.bookList.splice(index,1);
    }
    }

    //03 创建对象
    var p1 = new BookListManager();
    var p2 = new BookListManager();

    console.log(p1);
    console.log(p2);
    p1.init([{name:"城堡",author:"卡夫卡"}]);
    p2.init([{name:"一分钟学会H5开发",author:"乌拉乌拉"}]);

    console.log(p1);
    console.log(p2);
</script>

严格模式

说明

** "use strict" 注意点 :
1.在书写字符串的使用双引号和单引号都可以
2.字符串后面的分号可以省略
3.所有的字符必须全部小写
4.这个字符串只能拥有10个字符**

使用注意点

<script>
  "use strict";
   var obj1 = {
        name:"张三",
        showName:function(){
            console.log(this);
        }
    }

    obj1.showName();   //obj1            this--->obj1
    var showName = obj1.showName;
    showName();         //this丢失的问题  this--->window(非严格)|undefined(严格)

    obj1.showName.call(null);  
    //在严格模式下,函数内部的this绑定谁由第一个参数决定,如果没有传递那么是undefined,如果传入的值是null,那么绑定的就是null
</script>

1.arguments 接收实参的值
2.值类型&&引用类型的数据作为函数的参数传递,在非严格模式下,arguments和形参共享一份数据
3.重新设置了形参的值,arguments的值也会发生改变,在严格模式下,arguments和形参是独立的,他们之间没有关系,修改了形参的值对arguments没有影响的

<script>
  "use strict";
    function funcName(paramStr){
        console.log(paramStr);
        console.log(arguments[0]);

        //重新设置形参的值
        paramStr = "测试的字符串";
        console.log(arguments[0]);
    }
    var str = "demoStr";
    funcName(str);

    function funcName02(obj)
    {
        console.log(obj);
        console.log(arguments[0]);

        //重新设置obj的值
        obj = {age:20};
        console.log(obj);
        console.log(arguments[0]);
    }
    var obj = {
        name:"张三"
    };

    funcName02(obj);
</script>

严格模式的作用域

写在当前作用域的最顶端
作用范围
<script>
     // "use strict";     位置01 对f1和f2都有效
    function f1(){
     // "use strict";     位置02 对f1有效f2无效

        //a = 10;
    }
    function f2(){
    // "use strict"; 位置03  对f2有效f1无效
        b = 20;
    }
    f1();
    f2();
</script>

作用域

某个变量有( 起 ) 作用的范围
块级作用域, 在别的语言里有块级作用域, 但是在js中没有块级作用域
js中的作用域
词法作用域 - 动态作用域
词法作用域的访问规则:

变量和函数提升

js的执行顺序
<script>
    console.log(a);   //undefined ?
    var a = 10;

    f1();
    function f1(){
        console.log("f1");
    }
</script>
<script>
//    var n1 = "n1";
//    console.log(n1);                //n1
//
//    function test(){
//        console.log(n1);
//    }
//
//    test();                         //n1
//    var n1 = "new n1";
//    console.log(n1);                //new n1
//    test();                         //new n1


//      模拟变量和函数的提升
        var n1;
        function test(){
            console.log(n1);
        }
        var n1;
    n1 = "n1";
    console.log(n1);                //n1

    test();                         //n1
    n1= "new n1";
    console.log(n1);                //new n1
    test();                         //new n1
</script>
<script>
    f1();                   //10 ? 20
    function f1(){
        console.log(10);
    }

    f1();                   //20
    function f1(){
        console.log(20);
    }
    f1();                   //20
</script>
<script>
    console.log(demo);                      //
    var demo = "我是字符串";
    function demo(){
        console.log("我是函数");
    }

    console.log(demo);                      //

    //......
    var demo;
    function demo(){
        console.log("我是函数");
    }

    console.log(demo);                      //函数
    demo = "我是字符串";
    console.log(demo);                      //我是字符串


</script>
<script>
    console.log(test);                      //函数
    function test(){
        console.log("我是函数");
    }
    var test = "我是帅哥";
    console.log(test);                      //

    ///////变量声明(和函数同名的)不会提升
    function test(){
        console.log("我是函数");
    }
    console.log(test);                      //
    var test = "我是帅哥";
    console.log(test);
</script>
注意 : 如果是函数的表达式,那么在做函数声明提升的时候,仅仅只会把var 变量的名称(函数)提升到当前作用域的最顶端

作用域链

<script>

    var a = 10;
    function f1(){

        function f2(){

            var d = "demoD";
        }
    }

    function f3(){
        function f4(){

        }

        var b = "demoB";

        function f5(){

            var c = "demoC"
        }
    }
</script>
图解
**作用域链**
上一篇 下一篇

猜你喜欢

热点阅读