成员和静态成员
所谓实例 instance 对象
实例成员就是对象成员 也就是属性跟方法
就是对象本身绑定的属性跟方法
function Person(name,age) {
this.name=name;
this.age=age;
}
Person.prototype.show=function () {
console.log("请不要秀");
}
var per=new Person("小砌墙",16);
// 调用实例属性
/*console.log(per.name);
console.log(per.age);
// 调用实例方法
per.show();
那么什么是静态成员
绑定给构造函数本身的属性跟方法 就是静态成员
实例成员就用对象去调用
静态成员就用构造函数名去调用
不能混用
一般静态成员都是用来封装工具方法的
例如 : Math 不用new对象 使用方便
// 绑定静态属性
Person.country="中国";
// 绑定静态方法
Person.fight=function () {
console.log("少年强则国强");
}
// 调用静态属性
console.log(Person.country);
// 调用静态方法
Person.fight();
arguments对象
无论方法有没有声明形参 通过方法中默认自带的arguments对象
都可以获取的传入的所有实参
获取到的所有实参放入arguments这个伪数组里面
我们可以通过遍历取出每一个实参的值 进行使用
function show() {
// console.log(arguments);
for(var i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
}
// show();
// show(5,7,1,3)
show("关羽","张飞","刘备")
词法作用域
词法( 代码 )作用域, 就是代码在编写过程中体现出来的作用范围. 代码一旦写好,
不用执行, 作用范围就已经确定好了. 这个就是所谓词法作用域.
在js中没有块级作用域 大括号并不能限制变量的作用域
唯一能够限制变量作用域的就是函数
变量提升:
只能提升到当前作用域的第一行 局部提升到局部第一行
全局提升到全局第一行
函数提升
函数式声明的函数 将提升整个函数
解释型和编译型语言
js就是解释型语言 一行一行逐行逐句往下执行 执行一行 解析一行
java就是编译型语言:
运行之前 先编译 在运行
但是JS存在预解析阶段
* 当变量和函数同名时 该如何处理提升--------------------------
* 将提升函数 而忽略变量
console.log(demo);//是demo函数
function demo() {
console.log("我是demo方法");
}
var demo="我是demo变量";
console.log(demo);
// 提升后的代码
function demo() {
console.log("我是demo方法");
}
console.log(demo);
demo="我是demo变量";
当函数名相同时的提升-------------------------
后面的函数会覆盖之前的函数 无论在哪调用 都只能调用到后面的函数
func1();
function func1(){
console.log('1');
}
func1();
function func1(){
console.log('2');
}
//提升后的代码
function func1(){
console.log('2');
}
func1();
func1()
预解析是分作用域的--------------------------------------
//局部变量只能提升到局部位置第一行
//预解析是分段的----------------------------------
提升不会跨script标签
// console.log(a);//a is not defined 不存在跨标签提升 所以a变量不存在
// show(); //show is not defined 报错 函数提升也不会跨标签
script标签报错 只会影响当前script后面的代码
其他后面的script标签会继续执行
函数表达式声明不会被提升------------------------------------
// show(); show is not a function 因为show按照变量提升的规则
var show=function () {
console.log("haha ");
}
条件式函数声明------------------------------------------
条件式函数声明 不管条件式true还是false 都按照 变量提升规则
console.log(typeof func); //undefined
if(false){
function func(){
return 1;
}
}
console.log(typeof func);
作用域链
在js中唯一能够产生作用域的就是函数
也就是说 一个函数能够产生一个作用域
如果函数内部还有一个函数 那么就产生一个下级作用域
下级作用域里面还可以有函数 这样串联起来 就构成了 作用域链
内部函数可以调用外部函数作用域的数据 外部函数还可以调用更外部函数的作用域
这样链式结构就是作用域链
不在函数中的作用域就是全局作用域 也成为了0级链
一旦函数 那么就构成了 1级链
以此类推
函数内部的函数构成了 2级链
function f1() {
function f2() {
}
}
var num = 456;
function f3() {
function f4() {
}
}
callee和caller
callee是函数中arguments对象的一个属性
返回当前函数本身 也是代表当前函数 可以直接调用的
一旦在函数中 用callee调用 那就变成了 递归(函数自己调用自己)
递归要小心使用 必须有结束条件 否则就报错 调用死循环
function show() {
console.log("我是show函数");
console.log(arguments.callee);
console.log(arguments.callee==show);//true
}
show();
caller: 是当前函数名调用caller
如果当前函数的调用 放在了全局
那么 函数名.caller返回null
如果当前函数的调用 放到了 另一个函数里面
那么函数名.caller返回当前调用代码的外层函数本身
可以理解为一种上下文函数环境的获取
function demo() {
console.log(demo.caller);
}
function test() {
function qq() {
demo();
}
qq();
}
test();
总结:
当前方法在哪调用 就返回当前代码所在的外部函数
如果外部没有函数 返回null