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 (){})()
以下这个系统不报错,但这里并不是立即执行函数。