function math(){
var info = 'info'; //外部无法直接获取,成了私有属性
this.name = 'fun1'; //用this来赋值,则外部就可以根据对象.属性来获取这个值,成了public属性
this.add = function(a,b){
return a+b;
}
}
var m = new math();//注意需要用new来创建对象
console.log(m.info)//获取不到
console.log(m.name)//输出fun1
console.log(m.add(1,2))//输出3
(function(形参){
//会立即执行的代码块
}(实参))
顾名思义,立即执行函数在创建函数的同时会立即执行,没有绑定任何事件,也无法被调用,也无需等待任何一部操作,在被加载时就立即执行。function(){}是一个匿名函数,紧跟其后的()表示调用了该函数,并传入参数。
实例:
//修改微信内置对象实现微信分享
(function(cache_data){
window.wxData = {
img_url : 'http://xxx.xx.jpg',
link : location.href,
title : "标题",
desc : "描述"
};
}(window.cache_data));
闭包的思想就是外部无法直接访问某个方法(类)中的私有变量,只能通过该方法的内部方法来访问和操作该方法的私有变量。
实例:
$(function(){
var result = outter();//result等于outter的执行结果,也就是result指向Inner函数
result();//实质上为调用Inner函数
result();//多次调用Inner()时,函数内部访问的同一个a对象,因此输出结果是:1、2、3
result();
console.log('------直接访问outter私有变量------');
console.log(outter.a);//直接访问是无法访问到的,此时a就成了outter真正的内部变量
var product = new Product();
product.setName("商品1");
product.setPrice(9.99);
console.log(product.getName()+" --- "+product.getPrice());
});
function outter(){
var a = 0;
function inner(){
a += 1;
console.log(a);
}
return inner;
}
//闭包的另一种形式,也就是通常的bean对象形式
//外部无法直接访问Product的私有变量,只能通过Setter和getter来操作,Product内部函数访问的是同一个私有变量
function Product(){
var name;
var price;
this.setName = function(val){
name = val;
}
this.getName = function(){
return name;
}
this.setPrice = function(val){
price = val;
}
this.getPrice = function(){
return price;
}
}
另一种复杂一点的情况,也是面试常问的,这种问题最主要的明白,只有对象名后面跟上()才会真正调用对象指向的函数
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){//result[i]都指向一个function,因为该function还没有被调用,所以function内部都返回同一个对象i
return i;
};
}
return result;
}
var funcs = createFunctions();
//此时
//result[0] = function(){return i}
//result[1] = function(){return i}
//result[2] = function(){return i}
//....而i在createFunctions内部循环结束后i等于10
for (var i=0; i < funcs.length; i++){
console.log(funcs[i]());//此时才是真正调用内部函数
}
每个函数(类)都有prototype属性,可以用来动态为该函数添加方法。
$(function(){
//为Product函数绑定toString方法
Product.prototype.toString = function(){
return {
name:this._name,
price:this._price,
info:'prototype就是为函数(类)绑定方法'
}
}
var p1 = new Product('商品1',8.88);
var p2 = new Product('商品2',9.99);
console.log(p1.toString());//调用toString()
console.log(p2.toString());
});
function Product(name,price){
this._name = name;
this._price = price;
}
提现和封装思想。基于立即执行函数来实现,可以控制模块内部变量和方法的访问权限,大部分框架入jQuery都使用的大量的模块化语句。
var module = (function(形参) {
//内部变量和方法
//以return一个对象的形式来暴露方法或属性,以供外部调用
return{
}
})(实参);
模块内部的方法不会立即执行,只有外部调用时才会执行,形参实参可以为空。
实例:
$(function() {
//调用模块提供的属性或方法
console.log(module.description);
module.introduce('blysin');
module.printParam();
});
//创建一个模块化代码
var module = (function(param) {
var name = "module"; //private属性
function print(val) { //private方法
console.log('调用了print方法,输出:' + val);
}
function introduce(user) { //private方法
var words = user + 'is useing ' + name;
print(words);
}
function printParam(){
console.log(param);
}
//return的作用就是将私有的方法或属性暴露给外部,供外部调用
return {
description: "This is a simple "+name, //暴露一个属性
introduce: introduce,//暴露一个方法
printParam:printParam
}
})({
status:'正常',
isDebug:true
});
JavaScript开发者有必要理解apply、call与bind方法的不同点。它们的共同点是第一个参数都是this,即函数运行时依赖的上下文。
三者之中,call方法是最简单的,它等价于指定this值调用函数:
obj1.method.call(obj2,arg1,arg2...);
执行效果:让obje2对象执行obj1对象内的某个方法,arg为该方法的参数。
var user = {
name: "Rahul Mhatre",
whatIsYourName: function() {
console.log(this.name);
}
};
user.whatIsYourName(); // 输出"Rahul Mhatre",
var user2 = {
name: "Neha Sampat"
};
user.whatIsYourName.call(user2); // 输出"Neha Sampat"
apply方法与call方法类似。两者唯一的不同点在于,apply方法使用数组指定参数,而call方法每个参数单独需要指定:
var user = {
greet: "Hello!",
greetUser: function(userName) {
console.log(this.greet + " " + userName);
}
};
var greet1 = {
greet: "Hola"
};
user.greetUser.call(greet1, "Rahul"); // 输出"Hola Rahul"
user.greetUser.apply(greet1, ["Rahul"]); // 输出"Hola Rahul"
使用bind方法,可以为函数绑定this值,然后作为一个新的函数返回:
var user = {
greet: "Hello!",
greetUser: function(userName) {
console.log(this.greet + " " + userName);
}
};
var greetHola = user.greetUser.bind({greet: "Hola"});
var greetBonjour = user.greetUser.bind({greet: "Bonjour"});
greetHola("Rahul") // 输出"Hola Rahul"
greetBonjour("Rahul") // 输出"Bonjour Rahul"