var student={ name:"李白" , //student有一个name属性,值为"李白" grade:"初一" , //a、student有一个say属性,值为一个函数 //b、student有一个say方法 say:function(){ console.log("你好"); }, run:function(speed){ console.log("正在以"+speed+"米/秒的速度奔跑"); } }
var obj={}; obj.this=5; //语法错误 obj.0=10; //语法错误
obj["this"]=10
obj[3]=50 = obj["3"]=50
student["gender"]="男"
等价于: student.gender="男"
如果student对象中有gender属性,就修改gender属性的值为"男"
student.isFemale=true
student["children"]=[1,2,5]
student.toShanghai=function(){ console.log("正在去往上海的路上") }
var isMale=/123/;
==> var isMale=new RegExp("123")
function Person(name,age){ this.name=name; this.age=age; } var p1=new Person("赵云",18)
p1就是根据【Person构造函数】创建出来的对象
function CreateFunc(){ }
var p1=new Person();
_p1
this
,将this指向该实例(_p1) function fn(){ } var f1=new fn(); //f1就是fn的实例 function fn2(){ return "abc"; } var f2=new fn2(); //f2是fn2构造函数的实例
function fn3(){ return [1,3,5]; //数组是一个对象类型的值, //所以数组是一个复杂数据类型的值 //-->本次构造函数的真正返回值就是该数组 //-->不再是fn3构造函数的实例 } var f3=new fn3(); //f3还是fn3的实例吗?错 //f3值为[1,3,5]
并不是所谓的xxx extends yyy
function Person(){ this.say=function(){ console.log("你好") } } var p1=new Person(); var p2=new Person(); console.log(p1.say === p2.say); //false
Person.prototype.say=function(){ console.log("你好") }
Person.prototype = { //切记不能忘记 constructor:Person, say:function(){ console.log("你好"); }, run:function(){ console.log("正在进行百米冲刺"); } }
var o1={ age:2 }; var o2 = o1; o2.age=18; //1、修改了o2对象的age属性 //2、由于o2对象跟o1对象是同一个对象 //3、所以此时o1对象的age属性也被修改了
var o3={gender:"男",grade:"初三",group:"第五组",name:"张三"}; var o4={gender:"男",grade:"初三",group:"第五组",name:"李四"}; //上述代码中,如果使用拷贝继承对代码进行优化会非常和谐 //实现拷贝继承: //1、已经拥有了o3对象 //2、创建一个o3对象的拷贝(克隆):for...in循环 //3、修改克隆对象,把该对象的name属性改为"李四"
var source={name:"李白",age:15} var target={}; target.name=source.name target.age=source.age;
var students=[ {name:"",age:""}, {name:"",age:""} ]
function extend(target,source){ for(key in source){ target[key]=source[key]; } return target; } extend(target,source)
var source={name:"李白",age:15} //让target是一个新对象,同时拥有了name、age属性 var target={ ...source } var target2={ ...source,age:18 }
js var parent={ age:18,gender:"男"}; var student=Object.create(parent); //student.__proto__===parent
var o1={ say:function(){} } var o2=Object.create(o1);
function Animal(name,age,gender){ this.name=name; this.age=age; this.gender=gender;}function Person(name,age,gender,say){ this.name=name; this.age=age; this.gender=gender; this.say=function(){ }}
局限性:Animal(父类构造函数)的代码必须完全适用于Person(子类构造函数)
function Animal(name,age){ this.name=name; this.age=age;}function Person(name,age,address){ Animal.call(this,name); //this.name=name; //this.age=age; this.address=address;}
function Animal(){} var cat=new Animal(); //cat.__proto__:Animal.prototype //cat.__proto__.__proto__:根对象
var age=18; //age是在全局作用域中声明的变量:全局变量function f1(){ console.log(name); //可以访问到name变量 var name="周董" //name是f1函数内部声明的变量,所以name变量的作用域就是在f1函数内部 console.log(name); //可以访问到name变量 console.log(age); //age是全局作用域中声明的,所以age也可以访问}console.log(age); //也可以访问
//多级作用域 //-->1级作用域 var gender="男"; function fn(){ //问题: //gender:可以访问 //age: 可以访问 //height:不能访问 //-->2级作用域 return function(){ //问题: //gender: 通过一级一级作用域的查找,发现gender是全局作用域中声明的变量 //age: //height: console.log(gender); //-->3级作用域 var height=180; } var age=5; }
var name="张三"; function f1(){ var name="abc"; console.log(name); } f1();
var name="张三"; function f1(){ console.log(name); var name="abc"; } f1();
var name="张三"; function f1(){ console.log(name); var name="abc"; } f1();
var name="张三"; function f1(){ return function(){ console.log(name); } var name="abc"; } var fn=f1(); fn();
var name="张三"; function f1(){ return { say:function(){ console.log(name); var name="abc"; } } } var fn=f1();
function fn(){ var a=5; return function(){ a++; console.log(a); } } var f1=fn(); f1(); f1(); f1();
ES6之前
,函数内部的this是由该函数的调用方式决定的 var age=18; var p={ age:15 say:function(){ console.log(this.age);//window.age:18 } } var s1=p.say s1(); //函数调用
var age=18; var p={ age:15 say:function(){ console.log(this.age);//this:p //this.age->p.age:15 } } p.say()//方法调用
var age=18; var p={ age:15 say:function(){ //this:say构造函数的实例,实例中并没有age属性,值为:undefined console.log(this.age); } } new p.say()//构造函数调用 //相当于: var s1=p.say; new s1();
var length=21; function f1(){ console.log(this.length); } f1.call([1,3,5]) //3 f1.apply(this) //window.length:21 f1.call(5) //undefined
//-->1、首先查看本身有没有length属性
//-->2、如果本身没有该属性,那么去它的原型对象中查找
//-->3、如果原型对象中没有,那么就去原型对象的原型对象中查找,最终一直找到根对象(Object.prototype)
//-->4、最终都没有找到的话,我们认为该对象并没有该属性,如果获取该属性的值:undefined
Object.prototype.toString.call()
$.ajax({ success:function(){ console.log(this); //window }})
[1,3,5].map(function(){ console.log(this); //window})
$("div") `${$}` `${$('div')}`