JS变量+作用域

基本类型-栈内存

保存基本类型的变量保存的是值本身

 

 

引用类型-堆内存

保存引用类型的变量保存的并不是对象本身,而是一个指向该对象的引用地址

 

 

引用类型判断对象是否相等

    function equalObjs(a,b) {
        for (var p in a) {
            if (a[p] !== b[p]) return false;
        }
        true;
    }
    console.log(equalObjs(xm,xh));

引用类型判断数组是否相等

     equalArrays(a,1)">if (a.length !== b.length) ;
        var i = 0; i < a.length; i++) {
            if (a[i] !== b[i]) ;
    }

引用类型对象复制(浅拷贝:只拷贝一层)

     copyObj(obj) {
        var newObj = {};
         obj) {
            newObj[p] = obj[p];
        }
        return newObj;
    }
console.log(undefined==null); /**/
console.log(undefined===*/

从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象,当给变量赋新值时,此变量就不再指向原来的对象了;

数组是引用类型的,如题中b=a相当于a与b指向同一个地址,但是a=[4,44]之后改变了a的地址,所以b不会受到影响 为[4] . 后面又把a=b指向了同一个地址,此时为b添加元素,因为a、b的地址都没有改变,a也会随之改变,所以a为[4,44] . 

 

 

参数传递的本质是值的复制,由于person是引用类型,这里就相当于把person的地址复制给了函数setName的参数obj

     setName(obj) {
        obj.name = 'xm';
        obj = {};
        obj.name = 'xh';
    }
    var person = {};
    setName(person);
    console.log(person.name); xm
    obj = person

检测变量类型typeof

    console.log(typeof 4);//number
    console.log(typeof(4));typeof 'str');string
    console.log(typeof true);boolean
    console.log(typeof undefined);undefined
    console.log(null);object
    console.log(typeof []);typeof {});function () {});function
    console.log(typeof /a/);object

instanceof检测引用类型

不能检测基本数据类型,只要是基本数据类型和instanceof连用,返回的都是false

    console.log([] instanceof Array);true
    console.log([] instanceof Object);true
    console.log({} false
    console.log(1 instanceof Number);false
console.log(null false

有两个变量,分别是a = {name: 'xm'},b = [4],我们不用第三个变量来调换a和b的值

    var a = {name: 'xm'},b = [4];
    a=[a,b];
    b=a[0];
    a=a[1];

作用域与解析机制

 

全局变量容易被污染,少用

with(obj)可以延长作用域链,但不推荐使用

     {};
    person.name = 'xm';
    person.sex = 'male';
    var score = 4;
    
    with(person) {
        name = 'xh';
        sex = 'female';
        score = 44;
    }
    console.log(person.name);
    console.log(person.sex);
    console.log(score);

有3个按钮给每个按钮添加点击事件,希望每次点击时输出当前点击的是第几个按钮,但是目前不论点击哪个按钮,最终输出的都是4

原因:由于先绑定,后触发,给每个按钮绑定事件,但是在触发的时候i已经是循环完之后,i的值了

(1)单击方法导致的循环问题。提示:单击方法在循环外面定义

(2)在循环中调用,并将被点的按钮的型号传进去

<!DOCTYPE html>
<htmlhead>
    meta charset="utf-8"title>变量、作用域</>
    
bodybutton>1>2>3script type="text/javascript">
        // 错误代码
        var btns = document.getElementsByTagName('button);
            for ( i = 0; i < 3; i++) {
                btns[i].onclick function () {
                alert(i + 1);
            };
        }

        正确代码
        );
         fn(i){
            btns[i].onclick(){
                alert(i+);
            }
        }
        ( i;i<btns.length;i){
            fn(i);
        }
    script>

不存在的变量或函数会报错;不存在的属性或方法,返回undefined;||是短路操作,形如a||b,如果a的值转换成布尔值是true的话,a||b等于a;如果a的值转换成布尔值是false的话,a||b等于b

        console.log(person||(person='xm'));
        console.log(window.person||(window.person='xm'));

预解析

1. 以var 声明的变量 会预解析 ,赋值为undefined;没有var则不进行预解析
2. 以let 声明的变量 不会进行预解析 
3. 函数的声明会预解析 ,函数会被提升,然后从上到下执行代码的时候,输出fn,就是提升的函数
4. 函数表达式不进行预解析

 

 

案例1:

(1)      预解析:外层查找var,name和age为undefined

(2)      预解析:内层函数fn,函数在预解析时,已经提前进行了该函数的声明。函数内变量argument、name、age为undefined

(3)      正常执行:外层name从undefined变为’xm’,age从undefined变为18

(4)      正常执行:内层输出name为undefined

(5)      正常执行:内层name从undefined变为’xh’,age从undefined变为10

    var name = 'xm'var age = 18 fn(argument) {
        console.log(name); undefined
        var name = 'xh'var age = 10;
    }
    fn();

如果预解析时变量名与函数名重复,那么只预解析函数

 

案例2:

    console.log(a);
    var a = 1;var预解析之后是undefined*/

案例3:

    console.log(a);
    a = 1;没有预解析,报错*/

案例4:

    console.log(a); 预解析结果a()
    var a = 1;
    console.log(a); 正常赋值后执行1
     a() {
        console.log(2); 函数在预解析之后不再解析
    }
    console.log(a); 1
    var a = 33
     a() {
        console.log(4);
    }
    console.log(a); 3
    a(); 报错,此时a=3,不是函数

案例5:

函数内部没有var,不进行预解析。输出时查找外层a,输出1;赋值时对外层a进行操作

     fn() {
        console.log(a);
        a = 2;修改全局变量a
    }
    fn();
    console.log(a);

案例6:

函数参数也相当于var定义的局部变量,预解析为undefined。赋值时对参数a进行操作

     fn(a) {
        console.log(a);
        a = 2;对参数a进行操作,从undefined变为2,全局变量a没有改变
    }
    fn();
    console.log(a);

案例7:

函数参数也相当于var定义的局部变量,预解析为undefined。赋值时对参数a进行操作

     fn(a) {
        console.log(a);将全局变量赋值给参数,因此参数输出1
        a = 2;将参数从1变成2,全局变量没有改变
    }
    fn(a);执行时将全局变量a=1传入参数
    console.log(a);1

垃圾收集机制

解除变量引用的方法是将其设置为null

相关文章

kindeditor4.x代码高亮功能默认使用的是prettify插件,prett...
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代...
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小