JavaScript笔记(一)数组、对象、类型转换、作用域、函数、闭包、立即执行函数

数组

var arr = [1,"abc",undefined];


对象

var deng = {

  lastName : "deng";

}

属性名可以加双引号

半面向对象,半面向过程

前期面向过程,结构化后面向对象


typeof(123)  number

typeof("123")  string

typeof(true)  boolean

typeof(undefined)  undefined

typeof(null)  返回Object    以前null作为对象的占位符

此外还有object   function


类型转换

隐式

NaN == NaN

undefined == null

=== 是绝对等于 不发生类型转换

isNaN("abc") 结果 true  原因:先经过Number()的隐式类型转换 ////   isNaN("null") 结果 false    ////  isNaN("undefined") 结果 true 

++/--  +/-   Number转换

+ string 

-*/%   Number   ////    a *1  即 NaN*1 结果NaN 类型number

&& || ! Boolean

< > <= >=  有数字的话 先转数字然后比较    都是字符串的话则通过ASCII码

== !=    有隐式转换  1 == "1"   1 == true 这两个都是成立的     ////   特殊的:undefined == null  NaN != NaN   这两个都是成立的

显式转换

Number('123')    Number(true)转为1     Number(null)转为0     Number(undefined)转为NaN   Number('a')转为NaN    Number('123abc')转为NaN

ParseInt('123') 123     ParseInt('123abc') 123   ParseInt(123.3) 123    ParseInt(true) NaN    ParseInt(10, 16) 16radix取值范围2-36,这里基底radix为16 

Boolean()  除了空字符串都转为true

Sting()        

ToString(radix)  radix为目标进制  undefined null  不能使用该方法


未经声明不报错的:未定义a  typeof(a)不报错  typeof(typeof(a))返回的是String  因为typeof() 结果为字符串类型


 作用域

函数是特殊的对象,它也有属性如name prototype可访问

type.[[scope]] 存的作用域,不能访问,仅供javascript存取,就是我们所说的作用域,存了执行期上下文的集合

运行期上下文:当函数执行时,会创建一个称之为执行期上下文的内部对象,一个执行期上下文定义了一个函数执行时的上下文环境,每次执行时对应的执行期上下文都是独一无二的

查找对象:从作用域链顶端依次向下查找

         

闭包:内存泄露

闭包作用:

1、实现公有变量

2、可以做缓存(存储结构)

如函数中有对象,对象中有方法,方法其实就是函数,

  

3、可以实现封装,属性私有化

4、模块化开发防止污染全局变量


 立即执行函数

( function () { } () )     w3c推荐

( function () { } ) ();

利用小括号特点,依据是只有表达式才能被执行

函数声明     与   函数表达式

function test(){

  var a = 123;

var test = function () {

}

左边执行完后,test已经不是函数了,

延伸

 阿里面试题

      


函数两种写法  1、函数声明    2、匿名函数

1、函数的声明
function abc() {

}
2、命名函数表达式 (很少用,演化为匿名函数表达式)
=后面是表达式,abc已经无用了
var test = function abc() {

}

3、匿名函数表达式    (常用)
var demo = function () {

}

任意个数求和

function sum() {
    //sum.length 形参长度
    //arguments.length  实参长度  
    var result = 0;
    for(var i = 0; i < arguments.length; i++){
 
   result += arguments[i];
  
    }
    console.log(result);
}

递归

要点

1、找规律

2、找出口

js运行三部曲

语法分析、预编译、解释执行

预编译:

函数声明整体提升    变量声明提升

函数体预编译四部曲:

1、创建AO对象    (Activation Object)

2、找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

3、将实参值和形参统一

4、在函数体里找函数声明,值赋予函数体

imply gloable 暗示全局变量:任何变量,如果未经声明就赋值,此变量就为全局对象所有

一切声明的全局变量,全是window的属性

 全局预编译三部曲

1、创建GO对象    (Global  Object)

2、找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

3、在函数体里找函数声明,值赋予函数体

 

先生成GO,后AO,b是全局的

 

 

js特点:单线程、解释性语言

 闭包

  

当内部函数被保存到外部生成闭包

闭包会造成原有作用域链不释放,造成内存泄漏

闭包的作用:

1、实现公有变量

2、可以做缓存

3、可以实现封装,属性私有化

4、模块化开发,防止污染全局变量

举例:

1、累加器

function add() {
    var count = 0;
    function demo() {
        count ++;
        console.log(count);
    }
    return demo;
}

var counter = add();
counter();
counter();

2、做缓存

function  eater() {    
    var food = "";
    var obj = {
        eat : function () {
            console.log("i am eating " + food);
            food = "";    
        },
        push : function (myFood) {
            food = myFood;
        }
    }
    return obj;
}

var eater1 = eater();
eater1.push('banana');
eater1.eat();

立即执行函数     例如:初始化函数

执行完立即被释放

(function (a, b, c) {
    ...    
}(1, 2, 3));

var num = (function (a, b, c) {
    var d = a + b + c;
    return d;
}(1, 2, 3));

只有表达式才能被执行符号执行

定义函数有两种方式 1、函数函数声明 2、函数表达式

function test(){}  是函数声明,所以function test(){}() 会报错 \\\\    test 是表达式 test() 不会报错

var test = function (){}() 是函数表达式    var test = function (){}()会被执行 再执行test的话 test已经变为 undefined

被执行符号执行的函数 是 立即执行函数  执行完就不是函数了

+ test = function (){}()  +使其变为表达式  执行完后 test被放弃 此时打印便会报错

(function test(){})()  最外面的括号,则里面称为函数表达式,则可以立即执行,然后再演化为(function test(){})(),然后在演化为(function (){})() , 这便是立即执行函数的原理

W3C推荐:(function (){})()

以下这个系统不报错,但这里并不是立即执行函数。

原文地址:https://www.cnblogs.com/liyonghua/p/8286833.html