(1)构造器和类
当使用new运算符调用一个函数的时候,它总是返回一个对象,在函数体内部,这个对象称为this,即便在函数中不做任何特殊的事情,也会有this对象,如果不使用new调用,没有一条显式return语句的函数,都会返回undefined
注意:在js中,与php一样,当没有给构造器函数传递参数时,圆括号是可选的,因此
var son = new farther;
也是有效的
(2)返回对象(new 一个对象的过程)
当使用new调用任何函数,会发生
1在后台自动创建一个“空”的对象,通过this引用(指向)该对象
var this = {};
2任意给this添加属性
this.name = "weiwei";
3在函数的末尾,隐式的返回this对象
return this;
返回对象将会导致隐式的this失效,数组也一样,数组也是对象
function devil(){
var skills = {
kill:"fireball" //字符串用引号包裹
};
this.kill = "iceball";
return skills;
}
var satan = new devil(); //不传参可以不用加圆括号
console.log(satan.kill); //fireball
js构造函数显式返回对象导致原型链丢失
返回的任何this以外的内容,都将会导致instanceof运算符和constructor属性无法像预期那样工作
function egg(){
return {
content:"yellow"
};
}
var hen = new egg();
console.log(hen instanceof egg); //false
console.log(hen.constructor === egg); //false
console.log(hen.constructor === Object); // true
(3)遍历对象属性
var weiwei = {
favo:"play basket",
desc:"mild",
high:170
}
for(item in weiwei){
console.log(item + ":" + weiwei[item]);
}
昨天做题竟然遗忘了item就是遍历的键名,多练多练
(4)值完全相同的对象不相等
数组也是对象,所以嘛
console.log([1,2,3] === [1,2,3]); //false
值相同,引用不同的两个数组(对象),js对象比较引用,切记
(5)增强构造器(防止遗漏new)
function hero(){
if(!(this instanceof hero)){
return new hero();
}
this.weapon = "gun";
}
var yuefei = new hero();
var james = hero();
console.log(yuefei.weapon);
console.log(james.weapon);
this instanceof hero检查新创建的this对象是否是由hero创建的,当没有使用new,会指向全局对象
(6)函数有prototype属性,对象没有
constructor属性可写,因此不可靠
(7)当属性不是一个有效的标识符的时候,方括号表示法是必需的
//girl.look-like-height = "isgood"; //错误,不能用点
girl['look-like-good'] = "beauty";
console.log(girl['look-like-good']);
//console.log(girl['look-like-height']);
(8)js中的点号
var power = "air force";
var result = "hello".power;
console.log(result); //undefiend
对字符串使用点操作符,会将字符串直接量转换为对象,就好像执行了new String('hello'),但是没有power属性,所以返回undefined
(9)
构造函数实例化一个对象,相当于就只是提供了一个模板,实例就继承了构造器上的属性和方法,然后就没有构造器的事了,就只有隐式原型__proto__来连接实例与构造器的原型,也就是实例取代了构造器
构造器原型上方法里的this也指向新生成的实例,但是方法里嵌套函数,会导致嵌套函数里的this指向全局,也就是window,(在方法里return函数与定义一个函数表达式,再调用一下有什么区别?)
(10)对象没有prototype属性
var haha = {};
haha.prototype.hi = "lalala";
console.log(haha.hi);
(11)函数执行环境导致的差异
var weapon = {
weapon_type:"arrow",
attack:function(){
return console.log(this.weapon_type);
//错误:console.log(return this.weapon_type);
}
}
var james = weapon.attack;
james(); //undefined;
var james = weapon.attack;
james.call(weapon); //arrow
(12)实例化的对象都指向同一个构造器原型
(13)自由变量
当前作用域没有定义的变量
方法不仅可以添加在构造器的prototype上,也可以直接添加在构造器上
function Cat(){ this.eat = function(){} }
(14)原型实例---对html节点进行赋值添加事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>原型继承实例</title>
</head>
<body>
<div class="hotstone" id="hotstone">我要上传说,哈哈哈</div>
<script>
function getId(id){
this.element = document.getElementById(id);
//console.log(this.element);
}
getId.prototype.getInnerHtml =function(val){
if(val){
this.element.innerHTML = val;
return this; //为了进行链式调用,返回的是new出来的实例
}else{
return this.element.innerHTML;
}
}
getId.prototype.on =function(type,fn){
this.element.addEventListener(type,fn);
}
var hotstone = new getId('hotstone');
console.log(hotstone.getInnerHtml('西兰花伟大炮肯定会上传说'));
console.log(hotstone.getInnerHtml()); //getInnerHtml方法传值进行修改,不传值进行获取
//因为getInnerHtml()返回了this,因此可以进行链式调用
hotstone.getInnerHtml('8月我一定会回来的,哈哈哈').on('click',function(){
alert('我被点击了,啊!');
})
</script>
</body>
</html>