一.typeof
//4.typeof操作符 检测给定变量的数据类型
console.log("--04.typeof--");
//可能会返回"undefined" "boolean" "string" "number" "object" "function"这几个字符串
//typeof null返回的是object
var m1;
console.log(typeof m1);//undefined
var m11=false;
console.log(typeof m11);//boolean
var m2="";
console.log(typeof(m2));//string
var m22=11;
console.log(typeof m22);//number
//以下返回object,包括null,[],{}
var m3=null;
console.log(typeof m3);//object
var m4=[];
console.log(typeof m4);//object
var m5={};
console.log(typeof m5);//object
var m6=function(){}
console.log(typeof m6);//function
二.instanceof
三.apply()和call()
//2.apply()
//apply()和call()使用大致相同. 具体要调用的函数.apply(指定的作用域,[参数数组]); sum.apply(this,[num1,num2]);
//具体要调用的函数.call(指定的作用域,多个参数); sum.call(this,num1,num2);
//在B中调用 A.apply(this,arguments);则会调用A
function Su(num1,num2){
return num1+num2;
}
function callSu1(num1,num2){
return Su.apply(this,arguments);
}
function callSu2(num1,num2){
return Su.apply(this,[num1,num2]);
}
console.log(callSu1(10,20));//30
console.log(callSu2(10,20));//30
//call()
function callSu3(num1,num2){
return Su.call(this,num1,num2);
}
console.log(callSu3(19,20));
//!!!!!!!!1call()和apply()作用,扩充函数赖以运行的作用域
window.color="red";
var o={color:"blue"};
function sayColor(){
console.log(this.color);
}
sayColor();//red 默认sayColor()是作为全局函数定义的
//使用方法名调用,相当于var sayColor=function(){};
sayColor.call(this);//red 显式的在全局作用域中调用函数
sayColor.call(window);//red 显式的在全局作用域中调用函数
sayColor.call(o);//blue 此时函数体内的this对象指向了o
四.callee和caller
//每个函数中的几个隐含属性,arguments,callee,this,caller,length,prototype
//arguments.callee:指向拥有该arguments对象的函数,即当前函数
//arguments.callee.caller:当前函数的调用函数.即指向哪个函数 调用 了当前函数
//二.arguments.callee实现递归
function factorial(num){
if(num<=1){
return 1;
}else{
//arguments.callee指向拥有该arguments对象的函数,此处即为factorial函数
return num*arguments.callee(num-1);
}
}
//三.caller
function outer(){
inner();
}
function inner(){
console.log(inner.caller);//输出为outer这个函数
for(var i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
//输出outer函数.即指向outer函数
console.log(arguments.callee.caller);
}
outer();//调用outer函数
//没有块级作用域,if语句中的变量声明会被添加到当前 的 执行环境(此时为 全局环境)中
if(true){
var color="blue";//声明在此
}
console.log(color);//blue,在外面仍然能访问
for(var i=0;i<10;i++){
}
console.log(i);//10
//在此时并未声明zcolor,java中会由于zcolor未声明报错.js不会
function getColor(){
return zcolor;
}
console.log(getColor());//undefined
var zcolor="blue";
//先在getColor(){}函数内部的作用域中寻找zcolor的值,但是未找到.随后到外层作用域(即全局作用域中)寻找
console.log(getColor());//blue
六.闭包
参见
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
闭包就是能够读取其他函数内部变量的函数。
作用
1.可以读取函数内部的变量,
2就是让这些变量的值始终保持在内存中
原理:内部函数的作用域链 中 包含 外部函数的 作用域
原文思考题答案
//3.this在闭包中可能会发生变化
var name3 = "The window";
var Object3 = {
name3: "My Object",
getNameFunc: function() {
//保存this
var that = this; //2)走到这里,保存this.后面的return function(){..}直接返回,并未走里面
return function() {
console.log(that.name3); //My Object
return this.name3; //4)此时this为window
};
}
};
console.log(Object3.getNameFunc()());//The window
//1).该行,使用Object3调用,this当然是Object3
var oo = Object3.getNameFunc();
//3).该行,相当于使用window调用.
oo();
//!!作用域链的这种配置机制,导致闭包只能取得包含函数中任何变量的最后一个值
function createFun() {
var result = new Array();
for(var i = 0; i < 10; i++) {
result[i] = function() {
return i;
};
}
return result;
}
//createFun()返回result,result是一个function数组(包含多个function)
var funArr = createFun();
for(var i = 0; i < funArr.length; i++) {
var everyFunResult = funArr[i](); //执行每一个function
console.log(everyFunResult); //输出10次10
}
console.log(createFun());
//2.2!!!创建另一个匿名函数自执行 强制让闭包的行为符合预期
function createFunc() {
var result = new Array();
for(var i = 0; i < 10; i++) {
//定义一个匿名函数,并将 立即执行 该匿名函数 的 结果 赋值给数组
result[i] = function(num) {
return function() {
return num;
};
}(i); //!!!
}
return result;
}