//1. 把整个函数体加小括号包在小括号里面
(function (){}(
alert(0);
));
//2. 只把函数体放在小括号里,调用的小括号放在外面
(function (){
alert(0);
}) ();
// 也可以像以下这样使用自执行函数
+function (){
alert(0)
}()
-function (){
alert(0)
}()
!function (){
alert(0)
}()
~function (){
alert(0)
}()
^function (){
alert(0)
}()
// 上面的语法都可以让自执行函数跑起来
(function(w){
//写所有函数和变量的声明
//写功能逻辑代码
//如果需要,就通过window对象想外界暴露接口
// 例如: window.$ = w.$
})(window)
因为沙箱的本质就是要进行隔离,那么直接在沙箱中使用外界的内容会破坏这个隔离的基本原则,所以,将外界的东西通过传参的形式传入沙箱内进行使用,那么沙箱中使用的就完全都是沙箱自己的内容了。
有利于代码压缩,因为内置对象名称无法被压缩,如果作为参数传进来,那么我们使用的就是形参名,形参是可以被压缩的!
var arr = [1,2,3,4,5];
arr.forEach(function(value,index,arr){
console.log(value);
})
// forEach语法用法如上所示;(arr参数一般用不到)
// 我们可以来扒一扒forEach方法实现原理;
//假装给数组原型上加一个我们自己的forEach方法
Array.prototype.myForEach = function (callback){
// 这里this.的指向-->被Array构造函数new出来的对象(我们要用的那个数组)
for(var i = 0; i < this.length; i ++){
callback(this[i], i, this);
}
}
// forEach的原理基本实现完了,是不是很简单
// 下面我们可以调用一下试试看;
var arr1 = [1,2,3,4,5];
arr1.myForEach(function(value,index){
console.log(value);
})
// 是不是也能用哈
var arr = [1,2,3,4,5];
var result = arr.map(function(value,index){
console.log(value);
return value;
})
console.log(arr);
console.log(result);
//arr数组和result数组中存在的值都一样;
// 我们也可以来看看map方法的实现原理;
Array.prototype.myMap = function(callback){
var result = [];
for(var i = 0; i < this.length; i++){
var res = callback(this[i], i, this);
result.push(res);;
}
return result;
}
//值得一提的是map函数也可以传String Number等构造函数作为参数;
var arr1 = [1,2,3,4,5];
var res = arr1.myMap(String); // 数组每一项会变成string类型
console.log(res); //["1" , "2", "3", "4", "5"]
1.
function test(){
console.log(this);
}
var obj = {};
obj.test = test;
obj.test(); // this指向window
2.
var obj = {
test: function(){
console.log(this);
}
}
var test = obj.test;
test(); // this指向window
new obj.test(); // this指向test函数创建出来的对象
3.
var arr = [
function(){
console.log(this);
},
function(){
console.log(this);
}
];
arr[0](); // this指向这个数组对象
4.
var length = 10;
function test(){
arguments[0]();
}
test(function(){
console.log(this.length); // 这里this指向第一个参数;
// 所以length是1(只有一个参数);
})
5. // 工厂模式创建对象,this的指向
function Person(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
console.log(this);
return obj;
}
var p = Person("小明",18); //这里的this指向window;
6. // 寄生模式创建对象,this的对象
function Person(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
console.log(this);
return obj;
}
ar p = new Person("张学友", 18);
// this的指向是被Person创建出来的对象
//这里值得一说的是,左后return obj了 构造函数的return语句如果return一个引用类型的数据是可以改变new默认的this指向的;
function test(){
console.log(this);
}
test();
var obj = {
test: function(){
console.log(this);
}
}
obj.test();
obj["test"]();
function Person(){
console.log(this);
}
var p = new Person();
function test(a, b){
console.log(this);
return a + b;
}
var obj = {
name : "小红"
}
console.log(test.call(obj,1,2)); // 这里的this指向obj对象而不是window
var arr = []
var str = Object.prototype.toString.call(arr);
console.log(str); //[object Array];
// 通过借用Object原型上的toString方法 把this指向arr;
// 这里我们可以模拟实现一下Obejct.prototype.toString.call方法
Obejct.prototype.myToString = function(){
var res = "[";
res += typeof this;
res += " ";
res += this.constructor.name;
res += "]";
return res;
}
var arr = [];
var date = new date()
var str = Object.prototype.myToString.call(arr);
console.log(str); //[obejct Array];
var str = Object.prototype.myToString.call(date);
console.log(str); // [object Date]
// 这样我们就基本实现了 Object.prototype.toString.call方法的原理了
// 主要利用call欺骗构造函数;
function test(a, b){
console.log(this);
return a + b;
}
var obj = {
name : "小红"
}
console.log(test.call(obj,[1,2])); //this也是指向obj对象
方法如果第一个参数不传,则函数中的this会指向window对象!
如果call/apply方法第一个参数传入的值类型的数据,则会自动将其转换成对应的引用类型的数据,再将this指向这个引用类型的数据!
如果call/apply方法第一个参数传入的是null或者undefined那么this将会指向window对象
具体情况我们看下面代码
1.
function test(a, b){
console.log(this);
return a + b;
}
var obj = {
name : "小红"
};
console.log(test.call(1,2)) //this会指向window
2.
function test(a, b){
console.log(this);
return a + b;
};
var obj = {
name : "小红"
};
console.log(test.call("a",1,2)) //this会指向String
3.
function test(a, b){
console.log(this);
return a + b;
};
var obj = {
name : "小红"
};
console.log(test.call(null,1,2)) //this会指向window
var fakeArr = {
0: "a",
1: "b",
2: "c",
length: 3
};
var realArr = []
realArr = realArr.concat.apply(realArr, fakeArr);
realArr = realArr.push.apply(realArr, fakeArr);
realArr = Array.prototype.slice.call(fakeArr);
// 上述三种方法都可以让类数组转换为数组
// 讲到这里,我们也可以来模拟一下slice方法的实现原理
Array.prototype.mySlice = function (startIndex,endIndex){
var arr = [];
//这里应注意slice方法切割数组包括开头不包括结尾
startIndex = startIndex || 0;
endIndex = endIndex || arr.length;
for(var i = startIndex; i < endIndx; i++){
arr.push(this[i]);
}
return arr;
}
// 我们先用一般方法实现求最大值的功能
var arr = [22,33,4,666,12,22,34,56,21];
var max = arr[0];
for(var i = 1; i < arr.length; i++){
max = max > arr[i] ? max : arr[i];
}
console.log(max);
// 我们再用apply方法实现
max = Math.max.apply(Math,arr);
console.log(max);
// 用apply方法简单吧~~
function Person(){
//this 指向的是在Student中使用call方法调用Person的时候传进来的new创建的对象,所以这里通过this添加的所有的属性都添加给了Student中new创建的对象
this.name = "小明";
this.age = 18;
}
function Student(){
//this new创建的对象
Person.call(this);
//Person.call(new创建的对象)
//1. 调用Person函数
//2. 把Person函数中的this指向了new创建的这个对象
this.stuNo = 10086;
}
var stu = new Student();
console.log(stu.name); // 小明