JS 高级 06

作用域链变量搜索原则

  • 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();
    
    
    
    
    
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,750评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,065评论 1 10
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,145评论 0 13
  • 一、你不知道的JavaScript 1、作用域 作用域 LHS RHS RHS查询与简单地查找某个变量的值别无二...
    顶儿响叮当阅读 346评论 0 0
  • 如何控制alert中的换行?\n alert(“p\np”); 请编写一个JavaScript函数 parseQu...
    heyunqiang99阅读 1,084评论 0 6