zoukankan      html  css  js  c++  java
  • js原型,闭包,this,作用域

    闭包:http://www.cnblogs.com/onepixel/p/5036369.html
    一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),
    因而这些变量也是该表达式的一部分。闭包的特点:
      1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
      2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
      简单的说,Javascript允许使用内部函数---
    即函数定义和函数表达式位于另一个函数的函数体内。
    而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、
    参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,
    就会形成闭包。

    js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量
    (包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.
    也就是构建一个闭包,这些变量将不会被内存回收器所回收,
    只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,
    而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收.

    当一个内部函数被其外部的函数之外的变量所引用 就形成了一个闭包:
    function A(){
    function B(){
    console.log("hello colsure");
    }
    return B;
    }
    var c=new A();
    c();//hello colsure
    1定义一个普通的函数A
    2在A中去定义一个函数B
    3在A中返回B的引用
    4执行A()把返回的值赋值给c变量
    5执行c()

    一种写法:
    var result=[]//定义一个数组
    function foo(){
    var i=0;
    for(;i<3;1++){
    result[i]=(function(j){
    return function(){
    alert(j)
    }
    })(i)
    }
    }
    foo();
    result[0]()//0;
    result[1]()//1;
    result[2]()//2;
    //result[]()匿名函数的调用 返回的函数

    作用域
    定义:变量在申明他们的函数体意外的函数嵌套的任意函数体内都是有定义的.
    1、在函数体中定义的变量,除了自身以外在if语句、while语句和内嵌函数中访问
    2、 if while for 等代码块不能形成作用域。
    3、 如果一个变量没有用var去声明,window便拥有这个属性
    因此这个变量的作用域不属于这个函数 而是window对象
    function scop(){
    foo="aaa";
    console.log(foo);
    }
    scop();
    console.log(window.foo);//才能打印

    作用域链
    定义:一个函数体重嵌套了多层函数体,并在不同的函数体中定义了同一个变量
    ,当其中的一个函数去访问这个变量就形成了作用域链。
    foo = "window";
    function first(){
    var foo = "first";
    function second(){
    var foo = "second";
    console.log(foo);
    }
    function third(){
    console.log(foo);
    }
    second(); //second
    third(); //first
    }
    first();
    1.延长作用域链
    1 with
    foo = "window";
    function first(){
    var foo = "first";
    function second(){
    var foo = "second";
    console.log(foo);
    }
    function third(obj){
    console.log(foo); //first
    with (obj){
    console.log(foo); //obj
    }
    console.log(foo); //first
    }
    var obj = {foo:'obj'};
    third(obj);
    }
    first();
    在执行third 传递了一个obj 因为没有var定义所以是window的作用域
    形成了obj->third ->first->window 此时的obj的foo就是obj中的输出‘obj’
    当 with语句结束时 作用域链恢复正常
    2.try-catch

    this:
    定义:上下文
    在函数中,this总是指向当前所属对象,this只有在运行的时候才能确定具体的指向,就是调用的对象
    改变this指向
    1.对象的引用
    2.call apply 作用就是借用别人的方法来调用,就像调用自己的一样.
    window.name="window";
    function f(){
    console.log(this.name)
    }
    f();//window
    var obj={name:'obj'};
    f.call(obj);//obj

    原型:
    在JavaScript中有两种对象:普通的对象(Object)和函数对象(Function)
    函数对象定义:
    function f1(){

    }
    var f2=function(){

    }

    var f3=new Function('x,y','return x+y');

    var o1={};//objec
    var o2=new Object();//object
    var o3= new f1();//objec
    //f1 f2 f3 typeof :function

    在Javascript中创建对象有两种方式:对象字面量和使用new表达式,
    o1和o2的创建恰好对应了这两种方式

    定义:在js中每当创建函数对象时,对象都会有一些内置的属性,其中包括
    prototype和__proto__,prototype即是原型对象,是一个指针 指向construct和新增的属性和方法
    作用:主要是继承(在prototype中定义的属性个方法都是留给自己的
    '后代'用)

    __proto__:存在于普通对象和函数对象都有,作用是保存父类的prototype对象,js在通过new表达式
    创建一个对象的时候,通常会把prototype赋值给新建对象的__proto__属性,形成传承

    function f(){
    }
    f.prototype.foo="a";
    console.log(f.foo);//undifined
    var f1= new f();
    console.log(f1.foo);//a
    var f2 = new f();
    f2.foo='b';
    console.log(f2.foo);//b 来自实例 原型被覆盖了
    delete f2.foo;//删除 f2会先找自身的prototype是否有foo如果没有 沿着原型链往上寻找
    console.log(f2.foo)//a

    原型与in 操作符

    hasOwnProperty 实例和原型都是true
    hasPrototypeProperty 原型是true
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
    alert(this.name);
    };
    var person1 = new Person();
    var person2 = new Person();
    alert(person1.hasOwnProperty("name")); //false
    alert("name" in person1); //true
    person1.name = "Greg";
    alert(person1.name); //"Greg" ——来自实例
    alert(person1.hasOwnProperty("name")); //true
    alert("name" in person1); //true
    alert(person2.name); //"Nicholas" ——来自原型
    alert(person2.hasOwnProperty("name")); //false
    alert("name" in person2); //true
    delete person1.name;
    alert(person1.name); //"Nicholas" ——来自原型
    alert(person1.hasOwnProperty("name")); //false
    alert("name" in person1); //true

    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
    alert(this.name);
    };
    var person = new Person();
    alert(hasPrototypeProperty(person, "name")); //true
    person.name = "Greg";
    alert(hasPrototypeProperty(person, "name")); //false






























  • 相关阅读:
    HA分布式集群二hive配置
    win下写任务提交给集群
    win10下将spark的程序提交给远程集群中运行
    Scala快学笔记(三)
    Scala快学笔记(二)
    Scala快学笔记(一)
    统计学习方法 三 kNN
    统计学习方法 二 感知机
    fluent python(一)
    Codewar (1)
  • 原文地址:https://www.cnblogs.com/cylblogs/p/5217448.html
Copyright © 2011-2022 走看看