一、构造函数和普通函数的区别
在命名规则上,构造函数一般是首字母大写,普通函数遵照小驼峰式命名法。
在函数调用的时候:
function fn() { }
构造函数:1. new fn( )
2 .构造函数内部会创建一个新的对象,即f的实例
3. 函数内部的this指向 新创建的f的实例
4. 默认的返回值是f的实例
普通函数:1. fn( )
2. 在调用函数的内部不会创建新的对象
3. 函数内部的this指向调用函数的对象(如果没有对象调用,默认是window)
4. 返回值由return语句决定
构造函数的返回值:
有一个默认的返回值,新创建的对象(实例);
当手动添加返回值后(return语句):
1. 返回值是基本数据类型-->真正的返回值还是那个新创建的对象(实例)
2. 返回值是复杂数据类型(对象)-->真正的返回值是这个对象
二、Get/Set访问器
语法:
Object.defineProperty(obj, prop, descriptor)
参数:
obj:目标对象
prop:需要定义的属性或方法的名字。
descriptor:目标属性所拥有的特性。
可供定义的特性列表:
- value:属性的值
- writable:如果为false,属性的值就不能被重写。
- get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
- set:一旦目标属性被赋值,就会调回此方法。
- configurable:如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化。
- enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来。
1 Object.defineProperty(this, "price", { 2 get: function () {return price*0.9;}, 3 set: function (value) { 4 /*大概普通产品的价格都在0--1万*/ 5 if(value>10000) 6 { 7 alert('产品价格必须在0--1万之间'); 8 }else{ 9 price = value; 10 } 11 } 12 });
1 function Person() { 2 var age = new Date().getFullYear() - 18; 3 Object.defineProperty(this, "age", { 4 get: function () { alert("内部存储数据为:" + age); return new Date().getFullYear() - age; }, 5 set: function (value) { age = value; } 6 }); 7 }
使用一下代码进行测试:
1 var p = new Person(); 2 p.age = 1994; 3 alert("外部获取到的数据为:" + p.age);
三、函数声明和函数表达式的区别
函数声明是可以提升的,而函数表达式不可以提升。
当我们定义一个函数表达式,在这个表达式前面是访问不到的。
1 //函数声明,变量fn以及其实现被提升到顶部 2 function fn(){ 3 console.log('函数') 4 } 5 //函数表达式,仅变量fn2被提升到顶部,实现没有被提升 6 var fn2 = function(){ 7 console.log('函数变量形式') 8 }
四、设置某个属性是否可写
1 /*我们的需求:自动计算打折后的价格*/ 2 Object.defineProperty(this, "price", { 3 value:5000000, 4 writable: false, 5 });