JS 高级 06

作者: _MARPTS | 来源:发表于2018-05-25 11:29 被阅读0次

作用域链变量搜索原则

  • 1.在使用一个变量的时候,首先在当前作用域链中查找 , 如果没有就去上一级作用域链中查找,直到0级作用域链

闭包

  • 闭: 封闭 关闭的意思

  • 包: 包裹 包装的意思

  • 闭包技术:

    • 1.作用域: 内层作用域可以访问外层(内层作用域-->外层作用域),反过来不可以
    • 2.但是有的时候我们确实需要访问内层作用域(外层作用域->内层作用域)
    • 3.闭包技术就是一种可以间接访问封闭空间私有数据的方法
  • 访问数据:

    • 1.直接return
      • 一次性获取数据
      • 每次获取的不是同一份数据
    function fun(){
        var obj = {
            name: 'zs'
        }
        return obj;
    }
    
    var obj1 = fun();
    var obj2 = fun();
    console.log(obj1 == obj2); // false
    
    
    • 2.使用闭包,对直接返回数据进行函数包装
    function demo(){
        var obj = {
            name:'zs'
        }
        return function (){
            return obj;
        }
    }
    var fun = demo();
    var obj1 = fun();
    var obj2 = fun();
    console.log(obj1 == obj2);// true
    
    • 3.返回多个数据
    第一种方法
    function demo(){
        var name = 'ss';
        var des = 'des';
        return function(){
            return[name,des]
        }
    }
    var func = demo();
    var name1 = func()[0];
    var des1 = func()[1];
    console.log(name1,des1);
    
    第二种方法
    function demo(){
        var name = 'sa';
        var des = 's';
        return [
            function (){
                return name;
            },function (){
                return des;
            }
        ]
    }
    
    var func = demo();
    var name1 = fun[0]();
    var des1 = func[1]();
    console.log(name1,des1);
    
    第三种方法 :  对象保存
    function fun(){
        var name = 'd';
        var des = 'qq';
        return  {
            getName : function (){
                return name;
            },
            getDes : function (){
                return des;
            }
        }
    }
    
    var obj = fun();
    var name1 = obj.getName();
    var des1 = obj.getDes();
    console.log(name1,des1);
    
闭包获取和设置数据
  • 规范写法
    function fun(){
        var name = 'zs';
        var age = 20;
        return {
            getName : function (){
                return name;
            },
            setName : function (newName){
                if(newName == undefined)return;
                name = newName;
            },
            getAge : function (){
                return age;
            },
            setAge : function (newAge){
                if(newAge == defined)return;
                age = newAge;
            }
        }
    }
    var obj = fun();
    console.log(obj.getName());
    obj.setName('ls');
    console.log(obj.getName());
    obj.setName();
    console.log(obj.getName());
    
    注意点:
    1.如果形参名与变量名相同,形参名无法传入,所以闭包要注意形参名不能与数据变量名同名
    2.如果没有传参要做兼容处理
    
  • 注意点:
    • 1.如果形参名与变量名相同,形参名无法传入,所以闭包要注意形参名不能与数据变量名同名
    • 2.如果没有传参要做兼容处理
闭包技术的作用
  • 1.获取函数内部的数据只能通过指定的api(接口,方法)API application programming interface
  • 2.在设置数据的时候更加安全
  • 3.可以延长变量的生命周期
setTimeout 和闭包的执行
  • setTimeout: 延迟执行函数(只会执行一次)
  • setInterval: 每隔一定的时间执行一次(定时器)
  • 进程: 正在运行的应用程序(工厂)
  • 线程: 进程中用来执行任务的,同一时间只能执行一个任务(工人)
  • JS是单线程
  • 串行执行: 按照一定的顺序一个个的执行
  • 并发执行: 多个任务同时执行
  • 多线程: 有多条线程
  • 多线程的原理: CPU同一时间只会调度一个线程,CPU是来回调度多个线程,造成多个任务同时执行的假象
for( var i = 0 ; i <10 ; i++){
    setTimeout(function(){
        console.log(i)//10次10
    },0)
}
  • ==JS的任务执行顺序==
    • 1.渲染任务
    • 2.代码的主要任务
    • 3.事件性的任务(点击...)
    • 解释了为什么都是10;
  • 利用立即执行函数修正
第一种
for( var i = 0 ; i <10 ; i++){
    (function (j){
        setTimeout(function(){
        console.log(i);
    },0)
    })(i);
}
第二种
for( var i = 0 ; i <10 ; i++){
        setTimeout((function(j){
        return function(){
            console.log(j)
        }
    })(i),0)
}
div事件和闭包
  • 立即执行函数修正JS任务执行顺序问题
  • 方法两种:一;整体包装 二:函数包装(返回函数)
函数的特殊性
  • 函数:
    • 1.函数的也是一个对象
    • 2.函数可以调用+ 作为参数+ 返回值 + 传参
    • 3.函数可以创建作用域
  • 函数name的特点:
    • 只能获取,不能修改
函数的回调(作为参数传递)
  • 把一个函数作为其他函数的参数,称为函数的回调
  • 特殊情况
    • 把对象的方法作为函数的参数 ---> this 丢失
    var person ={
        name : 'zs',
        showName: function(){
            console.log(this.name);
        }
    }
    function func(callBack){
        callBack();// '' window默认name为空字符串
    }
    
    func(person.showName)
    
    解决方法 call
     var person ={
        name : 'zs',
        showName: function(){
            console.log(this.name);
        }
    }
    function func(callBack,callBackObj){
        callBack.call(callBackObj);// zs  让callBack的this绑定callBackObj 修正this指向
    }
    
    func(person.showName,person)
    
函数作为返回值
  • 函数可以作为其他函数的返回值
    • 计数器
    function func() {
        a =0;
        return function (){
            a++;
            return a;
        }
    }
    
    var fun = func();
    fun()
    
即时调用函数
  • 语法:
    • 1.(function(){})();
    • 2.(function(){}())
    • 3.+function (){
      }()
    • 4.-function (){
      }()
    • 5.!function (){
      }()
即时对象初始化
var dataObj = {
    name : 'zs',
    des : 'des',
    age: 20,
    init: function (){
        console.log('111')
    }
}
// 即时对象初始化
({
    name: 'zs',
    des : 'des',
    age: 20,
    init: function (){
        console.log('111')
    }
}).init();
==惰性函数(初始化,常用)==
  • 函数真正的内容需要执行一次才能确定,可以实现自我的更新
  • 场合: 需要做一次初始化的操作
惰性函数
function func(){
    console.log('func');
    func = function (){
        console.log('func-func');
    }
}
func();//func
func();//func
  • 注意点:

    • 1.更新前,添加到函数上的属性,更新后就访问不到了(引用地址更改)
    function foo(){
        console.log('foo');
        foo = function () {
            console.log('foo-foo');
        }
    }
    
    foo.des = 'des';
    console.log(foo.des);//des
    foo();
    console.log(foo.des);//undefined 
    
    • 2.把惰性函数赋值给一个变量,以变量方式来调用,无法更新惰性函数(执行的都是外层函数)
      function foo(){
        console.log('foo');
        foo = function (){
            console.log('foo-foo');
        }
    }
    var func = foo;
    func();//foo
    func();//foo
    
    • 3.把惰性函数赋值给对象的方法,以对象的方法来调用,执行的外层函数(引用地址修改)
    function foo(){
        console.log('foo');
        foo = function (){
            console.log('foo-foo');
        }
    }
    var obj = {name : 'zs'}
    obj.func = foo ;
    
    obj.func();//foo
    obj.func();//foo
    
面试题 01

以下创建对象的方式,错误的是:

    var obj4;
    obj4.name = "XMG";
    obj4.getName = function () {
        return this.name;
    };
    console.log(obj4);  //false
面试题 02

请给出以下代码的打印结果

function test(){};
console.log(typeof test); // function

var test = '2018';
面试题 03

请给出以下代码的输出结果

var f = new Number(true);

if(f == true){
    var a = 10;
}

function fn(){
    var b = 20;
    c = 30;
}

fn();
console.log(a); // 10 
console.log(b); // 报错
console.log(c); // 30
面试题 04

请给出以下代码额输出结果

var name = 'world!';

(function(){
    if(tyopeof name === 'undefined'){
        var name = '张三';
        console.log('hi'+name);
    }eles{
        console.log('hello'+name);
    }
})();

// 结果: hi张三
面试题 05

请给出以下代码额输出结果


var a = {} , b = Object.prototype;
console.log([a.prototype === 
b,Object.getPrototypeOf(a)===b])
    //A [fasle true]
    //B [false false]
    //C [true  true]
    //D [true false]
// 结果 A
面试题 06

请给出下面代码额输出结果

function f() {}
    var a = f.prototype;

    //Object.getPrototypeOf(对象)  用于获取实例对象的原型对象 这里把f 作为一个实例,他的原型对象是Function.prototype
    var b = Object.getPrototypeOf(f);
    
    console.log(a === b);   // false | true

    console.log((b == f)); // false | true
    
    结果 false  false
面试题 07

请给出以下代码的输出结果

   function foo() { }
    var oldName = foo.name;
    foo.name = "bar";

    console.log(oldName);  // "foo"
    console.log(foo.name);  //  "foo"

    console.log(oldName === foo.name); //  true
    console.log([oldName, foo.name]); // ["foo","foo"]
面试题 08

请给出以下代码的输出结果

console.log(Array.isArray(Array.prototype))
// true

console.log(Object.prototype.toString.call(Array.prototype)); // [object Array]
面试题 08

请给出以下代码的输出结果

// [] [0] [1] 在条件判断为真,在== 值判断
if([0]){
    console.log([0]== true);
}else {
    console.log('NO');
}

 结果 false

if([2]){
    console.log([2]== true);
}else {
    console.log('NO');
}

结果 false

if([1]){
    console.log([1]== true);
}else {
    console.log('NO');
}
true == 1
结果 true 
面试题 09
// Fuction.prototype 是匿名函数
function f(){}
    var parent = Object.getPrototypeOf(f);
    
    console.log(f.name);//f
    console.log(parent.name);//''
}
面试题 10
(function(){
        var x = y = 1;
})()
    console.log(y); //能够获取y的值吗?  1
    console.log(x); //能够获取x的值吗?  报错
设计模式简单说明
  • 设计模式 ---> 解决问题的套路

  • 在开发中总结的一套方法,专门用来解决一类问题

  • 要求:设计一套系统需要设计模式(架构师)

  • 来源: 建筑行业

    • 设计模式的四人帮
  • 常见的设计模式(23): 单粒(例)模式, 代理委托模式,观察者模式,中介模式...

  • <<设计模式>> , <<大话设计模式>>,<<大话数据结构>>

  • 编程就是: 数据结构 + 算法

==工厂模式==

  • 核心步骤:
    • 1.提供一个父构造函数(开了一家工厂)
    • 2.设置父构造函数的原型对象(产品公共的一些东西)
    • 3.在父构造函数上提供一个静态的工厂方法(生产产品)
    • 4.定制合作伙伴
    • 5.使用父构造函数的静态工厂方法创建对象
    1.提供一个父构造函数(开了一家工厂)
    function PhoneMake (){
        
    }
    2.设置父构造函数的原型对象(产品公共的一些东西)
    PhoneMake.prototype.logDes = function (){
        
    }
    3.在父构造函数上提供一个静态的工厂方法(生产产品)
    PhoneMake.factory = function (){
        console.log(this.des)
    }
    4.定制合作伙伴
    PhoneMake.iphone = function(){
        this.des = ''
    }
    PhoneMake.vivo = function(){
        this.des = ''
    
    PhoneMake.oppo = function(){
        this.des = ''
    }
    5.使用父构造函数的静态工厂方法创建对象
     var iphone = PhoneMake.factory('iPhone');
    iphone.logDes();
    
    var vivo = PhoneMake.factory('vivo');
    vivo.logDes();
    
    var oppo = PhoneMake.factory('oppo');
    oppo.logDes();
    
    var meizu = PhoneMake.factory('meizu');
    meizu.logDes();
    
    
    
    
    
    

相关文章

网友评论

    本文标题:JS 高级 06

    本文链接:https://www.haomeiwen.com/subject/efmyjftx.html