day07
作用域
私人可以使用公家的东西 公家不能使用私人的 if while for do while 的大括号根本就不是作用域 只有函数才有私有空间
预解析
// 在代码执行之前 对代码进行通读并且解释 //只解析两部分内容 // 1. var 声明的变量名; // => 仅仅是对var 声明的变量提前声明 暂时不赋值 // 2. 声明式的函数 // => 对函数名字提前声明 并且直接给这个函数名赋值了 一个函数 // => 赋值式的函数按照 var 变量的规则进行 解释 // 注意点: // 打开浏览器 只会解析全局代码 // 不对函数内的代码进行预解析 // 函数内的代码 仅仅会在函数调用的时候才会 预解析
//函数 //fn() //function fn(){console.log('卧榻之侧岂容他人鼾睡')} //fn() // 打开浏览器 // 1.fn() // 2.function fn(){console.log('卧榻之侧岂容他人鼾睡')} // 3.fn() // 预解析 // 1.不需要 // 2.需要 声明了一个fn的变量 并且将函数赋值给了 fn // 3. 不需要 // 代码执行 // 1. fn() // => 把fn当做一个函数用 因为解析的时候已经声明了一个fn变量并且给他赋值为一个 // 函数所以 这里会正常调用 // 2. fn() // 跟上面一样 // 等价于 // function fn(){console.log('卧榻之侧岂容他人鼾睡')} // fn() // fn()
预解析重名问题
// fn(); // function fn(){console.log('hello world')} // fn(); // var fn = 100; // fn(); // 预解析 // 1.不需要 // 2.需要 声明一个fn的变量并且赋值为一个函数 // 3.不需要 // 4. 需要 // => 声明一个fn的变量 暂时不赋值 // 5.不需要 // 预解析结束 fn变量存在并且是一个函数 // 执行 // 1. fn() // => 正常调用 // 2. fn() // => 同上 // 3. fn =100 // fn 本来是个函数 但是此刻赋值为100 把函数覆盖了 // 4.fn() // 把fn当做一个函数来看待 但是上一步 fn不再是函数了 // fn is not a function ;
函数再两个阶段都做了什么
内存
栈内存
基本数据类型
函数名在 栈内存
堆内存
复杂数据类型
函数体再堆内存
// 函数定义阶段 // 1-1 现在堆内存中开辟空间 // 1-2 把函数体内的代码 原样复制到空间内(我们写代码写在硬盘上) // 1-3 把内存的地址 赋值给栈内存的函数名 //函数调用阶段 // 2-1 按照函数名存的地址去找到对应的函数体 // 先判断栈内存中是否有这个变量 // 如果存在 也会判断里边是否存储的还一个函数体 // 2-2 在调用栈 内开辟一个新的 函数执行空间 (一个函数可以被多次调用为了避免一个调用出现的结果影响所有的调用 //所以每次的调用都会申请一个执行空间) // 2-3 在执行空间内 给形参赋值 // 2-4 在执行空间内 对函数体内的代码进行预解析 // 2-5 在执行空间内 对函数体内的代码 执行一遍 // 2-6 完成以后 这个执行空间被销毁 或者理解为空间被收回
作用域
//全局作用域 // 一个html 页面打开这就是一个全局作用域 // => window (了解) // 私有作用域 局部作用域 // 只有函数才有 if while do while for 他们都没有局部作用域 // 作用域的上下级关系 // 定义在哪个作用域内的函数 就是哪个作用域的子级作用域
变量的定义机制
// 变量的定义 // 定义在哪个作用域下 这个变量就是哪个作用域的私有变量 // 只能在这个作用域下或者这个作用域的子级作用域内使用 // 不能在父级作用域使用 = >
var n1 = 100;
function fn1(){
var n2 = 200; // n2是fn1的私有变量 只能在fn1下 或者fn1的子级下面使用
console.log(n2);
console.log(n1);
}
fn1()
console.log(n2);
变量的访问机制
//变量的访问 // 首先在自己的作用域查找 如果有 那么直接使用 // 如果没有自动到父作用域查找 父作用域有 那么就使用 // 如果还没有 再往上一级 直到全局作用域 发现还没有 那么 报错 // xx is not defined
// var n = 100;
function fn2(){
// var n = 200;
function fn3(){
// var n = 300;
console.log(n);
}
fn3();
}
// fn2()
// fn3()
fn2()
变量的赋值机制
// 变量的赋值 // 先在自己的作用域内部查找 如果有直接赋值 // 如果没有自动到父作用域查找 父作用域有 那么就使用 停止查找 // 父作用域如果没有再往上到父级 直到 全局作用域 // 那么就把这个变量定义为全局变量 再进行赋值
// var a=b=10; // a = 20; // b = 20; //console.log(a) //console.log(b) //预解析 // 仅仅是声明一个全局变量a //执行代码 // 1. b = 10 标准的变量赋值 // 这时候 全局没有b 那么b当做了一个全局变量 并赋值 // 2. a = b // var a=b; // a = 20; // b = 20; // console.log(a) // console.log(b) // 预解析 // 声明 a 是一个全局变量 //执行 //a=b // 先访问b 再赋值a // 访问b的时候 因为b 不存在 直接报错 // var n = 100; function fn5(){ // var n = 200; n = 500; } fn5() console.log(n)
递归函数
//递归函数 // 自己调用自己 //一定要设置好结束条件 //技巧 // 写一个函数 // 写好结束条件 // 没有达到结束条件 不要忘了return
// 10!
// 循环
var num = 1;
for(var i=1;i<=10;i++){
num*=i;
}
alert(num);
// 阶乘 至少是 1
// 1当做结束条件
// 10*fn(9)
// 10*9*fn(8)
// 10*9*8*fn(7)
//10*9*8*7*6*5*4*3*2*f(1)
// function fn(num){
// if(num == 1) return 1;
// return num*fn(num-1);
// }
对象
// 对象复杂的数据类型 // 万物皆对象 // 人 姓名:王* 年龄 19 身高:183cm 好人:true 唱歌: 跳舞 谈恋爱 打篮球 // 笔记本: 尺寸:15 价格:8888 // js对象跟这个也是一样 // 键值对的集合 键和值之间: 键值对之间逗号隔开 // 无序的数值集合 可以是任意类型//建议使用第一种来创建对象 // 键的名字按照变量的命名规则 规范 // 不要有重复 后边 会覆盖前面 // 可以使用纯数字 作为键名 自动把数字排到最前面 // 也可以使用特殊符号作为键名 // 键的 可加单引号 可不加单引号 但是如果用特殊符号作为键名 必须加单引号 // 建议使用字符串作为键名
创建对象的两种方式**
var wangzhen = {
'username':'wangzhen',
'age':18,
goodman:true,
singing:function(){
console.log('窗外的麻雀在电线杆上撒粮');
},
love:function(){
console.log('过了这个村我在下个村等你')
}
}
wangzhen.sex = 1;
alert(wangzhen.sex)
// alert(typeof wangzhen) // object
alert(wangzhen.username) // 查看静态属性不用加()
wangzhen.love() // 调用动态方法 需要加()
字面量的创建
wangzhen.love() // 调用动态方法 需要加()
// 使用内置的工具(函数)来创建对象
var yinghao = new Object();
yinghao.name = 'ahao';
yinghao.age = 1;
yinghao.eating = function(){
console.log('正在吃')
}
使用内置工具(函数)来创建对象
对象的操作
增删改查
var jianzeng = {
name:'jiangjiang',
age:18,
ball:function(){
return '千锋白巧克力'
}
}
// 增
// jianzeng.height = '181cm';
// alert(jianzeng.height)
// delete
// alert(jianzeng.age);
// delete jianzeng.age;
// alert(jianzeng.age);
// 改
//重新赋值就是改的过程
// alert(jianzeng.name);
// jianzeng.name = 'xiaojiang'
// // alert(jianzeng.name);
// //查
// alert(jianzeng.age) // 查看静态属性
// alert(jianzeng.ball())//调用动态方法
另一种方法
// 增 对象名['键名'] = 值 // delete 对象名['键名'] = 值 // 对象名['键名'] = 值 //对象名['键名'] var pengpeng = { name:'rock', age:18, 1:666, 2:888, 'aaa^bbb':999, 'ccc-ddd':777 } // //alert(pengpeng.1);报错 // alert(pengpeng['1']) // // alert(pengpeng.aaa^bbb) // alert(pengpeng['aaa^bbb']) //当对象的键名字中有 纯数字 特殊符号 // 这个时候 增删改查 要使用 中括号的方式巧用