目录
1.数据属性的特征
//设置一个对象的原始属性
var obj={
name:'zhangsan',
age:12,
sex:'男',
}
//Object.defineProperty //只能设置某一个对象中的某一个属性的原始属性
Object.defineProperty(obj,'name',{
configurable:false, //默认true
enumerable:false, //默认true 能否被遍历(枚举)
writable:false, //默认true
value:'lisi',
})
console.log(obj); //{ age: 12, sex: '男' }
console.log(obj.name); //lisi
obj.name="xiaoming";
console.log(obj.name); //lisi 设置了不可被修改
delete obj.name;
console.log(obj.name); //lisi 设置了不可被删除
for(var k in obj){
console.log(obj[k]); //没有显示 设置了不可被枚举
}
//想要知道某个属性的原始属性 Object.getOwnPropertyDescriptor()
var res=Object.getOwnPropertyDescriptor(obj,'name');
console.log(res);
//一次设置对象的多个属性的原始属性
Object.defineProperties(obj,{
'sex':{
configurable:false,
},
'age':{
configurable:false,
}
})
2.构造器属性
_name 这种属性我们不希望通过外部访问
var obj={
_num:0
};
//要求obj.num可以访问到 obj.num=num(一个数值)
Object.defineProperty(obj,'num',{
//当没有设置这两个值,会隐式调用,如果设置了,调用设置的
set(num){
this._num=num
},//在num的值被设置时,调用
get(){
return '数字:'+this._num
},//在num的值被获取时,被调用
})
console.log(obj.num); //数字:0
obj.num=5;
console.log(obj.num); //数字:5
3.对象序列化
obj.toString()
转换成json字符串 JSON.stringify(obj)
转换为查询字符串(表单) var qs=require(querystring)
qs.stringify(obj)
//转换JSON字符串
var user_info={
username:'zhangsan',
password:'123456',
}
var j_str=JSON.stringify(user_info);
console.log(j_str); //{"username":"zhangsan","password":"123456"}
拿到JSON字符串,如何转为对象?
var user_info2=JSON.parse(j_str);//反序列化
console.log(user_info2);//{ username: 'zhangsan', password: '123456' }
console.log(user_info2.username); //zhangsan
自定义JSON字符串,转为对象
//自定义JSON字符串
var str='{"username":"zhangsan","age":10,"sex":"男"}';
var str_obj=JSON.parse(str)//反序列化
console.log(str_obj.age); //10
4.函数
作用:封装,解决代码冗余,充当构造函数
① 自定义函数
//自定义函数
function test(){
//功能体
console.log(1);
}
var t1=function(){
//功能体
console.log(2);
}
test(); //1
t1(); //2
②区别
//区别 变量提升
test(); //1
t1(); //TypeError
function test(){ //变量提升时,函数名和功能体都会提升
//功能体
console.log(1);
}
var t1=function(){ //变量提升时,只会提升变量名
//功能体
console.log(2);
}
③函数中形参的使用
function cook(a="番茄",b="鸡蛋"){ //ab称为形参,参数有默认值,将默认值放在末尾
console.log(a+"炒"+b);
}
cook(); //番茄炒鸡蛋
cook("萝卜"); //萝卜炒鸡蛋
④函数中功能体
var c=2;
function cook(a,b="鸡蛋"){
var c=1;
console.log(c); //1
console.log(a+"炒"+b); //萝卜炒鸡蛋
}
cook("萝卜");
var c=2;
function cook(a,b="鸡蛋"){
console.log(c); //2
console.log(a+"炒"+b); //萝卜炒鸡蛋
}
cook("萝卜");
function cook(a,b="鸡蛋"){
console.log(c); //undefined
var c=2;
console.log(a+"炒"+b); //萝卜炒鸡蛋
}
cook("萝卜");
var a=2;
function cook(a,b="鸡蛋"){
console.log(c); //undefined
var c=2;
console.log(a+"炒"+b); //萝卜炒鸡蛋
}
cook("萝卜");
return 返回只有一个,并且在返回后所有代码都无效.
5.函数的内部属性
arguments是一个类数组对象,是函数的内部属性,包含传入函数的所有参数
注意:类数组对象不是数组,不能使用数组方法
类数组对象特征:内部下标和数组类似,并且有length属性。
function add(a,b){
console.log(arguments); //[Arguments] { '0': 1, '1': 2 }
console.log(arguments.length); //2
console.log(arguments[0]); //1
}
add(1,2)
在arguments中属性callee,该属性指向拥有arguments的函数
//递归函数 传入一个数10*9*8...*1
//需要在某个时刻跳出循环
function dg(num){
if(num<=1)
return 1;
else
return num*dg(num-1);
}
var res=dg(10);
console.log(res);
function dg(num){
if(num<=1)
return 1;
else
return num*arguments.callee(num-1);
}
var res=dg(10);
console.log(res);
this
var a=2;
function add(a){
console.log(a); //1
}
add(1);
//函数内部有this属性,指向函数所在的环境
a=2; //node有点特殊,前面加var 输出是defined
function add(){
console.log(this.a); //2 node环境下 ,this指向 global
}
add();
var a=2;
function add(){
console.log(this.a); //2 浏览器环境下 ,this指向 window
var a=1;
console.log(a); //1
}
add();
var a=2;
var obj={
a:3,
add(){
console.log(this.a); //3
}
}
obj.add();
IIFE jses5中的块级作用域(模拟)
隔离作用域,防止污染全局
(function(){ //可以使函数在声明后,立即调用
var a=4;
console.log(a);
})()
函数调用
//改变函数的执行环境
name="xiaoming";
function sayName(){
console.log(this.name);
}
var obj1={
name:"zhangsan",
}
var obj2={
name:"lisi",
}
sayName(); //xiaoming
sayName.call(obj1); //zhangsan //将sayName中的this指向改为obj1
sayName.apply(obj1); //zhangsan
sayName.bind(obj1)(); //zhangsan
区别
name="xiaoming";
function sayName(a,b){
console.log(this.name);
console.log(a+b);
}
var obj1={
name:"zhangsan",
}
var obj2={
name:"lisi",
}
sayName(1,2); //xiaoming 3
sayName.call(obj1,1,2); //zhangsan 3
sayName.apply(obj1,[1,2]); //zhangsan 3
sayName.bind(obj1)(1,2); //zhangsan 3 //返回的是一个方法
函数的本质
//函数的本质(构造器函数)
function Animal(name,age){
this.name=name;
this.age=age;
}
Animal.prototype.sayHello=function(){
console.log('hello');
}
var d1=new Animal('小白',2);
console.log(d1); //Animal { name: '小白', age: 2 }
console.dir(Animal);//[Function: Animal]
d1.sayHello(); //hello
函数的应用
//函数名本身就是变量,所以函数可以当作值来使用(参数,返回值)
//参数
//比如定时器,AJAX的使用,数组遍历
var arr=[1,2,3,4,5];
arr.forEach(function(v){
console.log(v); //1 2 3 4 5
});
setTimeout(function(){
console.log(111); //111
},2000);
//作为返回值
function add(a,b){
return function(){
return a+b;
}
}
var res=add(1,2);
console.log(res()); //3
6.闭包
①函数的内部嵌套函数
②函数的内部引用外部的变量
③闭包不会被垃圾回收机制回收
function getNum(){
var num=0;
return function(){
return num;
}
}
var num=getNum();
console.log(num()); //0
function getNum(){
var num=0;
console.log(++num);
}
getNum(); //1
getNum(); //1
function getNum(){
var num=0;
return function(){
var n=0;
console.log(++num);
console.log(++n);
}
}
getNum()(); //1 1 //这样写我们的getNum将被销毁,所以num一直为0
getNum()(); //1 1
getNum()(); //1 1
var res=getNum(); //保持引用的关系
res(); //1 1
res(); //2 1
res(); //3 1