有New就会发生这三步,没有New就当普通函数执行,第一步隐式的加上this={},里面有
一个属性__proto__:,
这个proto的用途就是当你访问对象的属性时,如果没有这个属性,就会通过__proto__指向的索引到Person.prototype上找有没有你要的属性,相当于连接的关系,把原型和自己连接在一起了
任何一个执行期上下文的this都是指向window,但是new过之后就指向对象
什么时候用new呢,比如:
我们需要用构造函数构造对象的时候就用new,需要通过构造函数批量生产对象,加了new以后,构造函数里面隐式的产生了var this 以及return this
构造函数首字母都大写
例一:
<script>
var MrX={
name:"MrX",
sex:"male",
age:40,
health:100,
smoke:function(){//这是方法
console.log("i like smoking");
MrX.health--;
},
run:function (){
console.log("i like running");
MrX.health++;
}
}
</script>
也可以将MrX改为this
<script>
var MrX={
name:"MrX",
sex:"male",
age:40,
health:100,
smoke:function(){
console.log("i like smoking");
this.health--;
},
run:function (){
console.log("i like running");
this.health++;
}
}
</script>
<!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>Document</title>
</head>
<body>
<script>
//增删查改
var MrX={
name:"MrX",
sex:"male",
age:40,
health:100,
smoke:function(){
console.log("i like smoking");
MrX.health--;//也可写成this.health
},
run:function (){
console.log("i like running");
MrX.health++;//也可写成this.health
},
//传参
Ginseng:function (somebody){
MrX.boyfriend=somebody;
},
}
//给一个对象增加属性或方法,直接对象.东西就行了
MrX.fridend="MrS";
//查看
console.log(MrX.sex);
//修改
MrX.age=20;
console.log(MrX.age);
//删除
delete MrX.name;//delete空格+属性
</script>
<script>
// 对象的创建方法 构造函数时为了生产对象的,通过不同的调用可以产生相似或者不同的对象
// 1:var obj={} plainObjiect 对象字面量/对象直接量
// 2:构造函数
// 1) 系统自带的构造函数 Object()
// 2) 自定义
var obj=new Object();//相当于var obj={};
obj.name='abc';
obj.sex='male';
//增加属性和方法
obj.say=function (){
name: ""
} //用等号,不用分号这里
//自定义改造函数:大驼峰式命名规则
function Car(color){
this.color=color;
this.name="BMW";
this.height="1400";
this.lang="4900";
this.health=100
this.run=function (){
this.health--;
}
}
var car=new Car('red');
var car1=new Car('green');
function Student(name,age,sex){
// var this={
// name:""
// age:""
// };
this.name=name;
this.age=age;
this.sex=sex;
this.grade=2019;
//return this;
}
var student=new Student("zhangsan",17,"male");
</script>
<!-- 构造函数内部原理 必须加new,本来是函数,加了new之后,就有了构造函数的功能
1:在函数体最前面隐式的加上this={}
2:执行this.xxx=xxx;
3:隐式的返回this
-->
<!-- 包装类 -->
<script>
//数字对象
var num=new Number(123);
//字符串对象
var str=new String('abc');
//布尔对象
var bol=new Boolean('true');
var str="abcd";
str.length=2;//自己没有length 系统创建的new String('abcd').length=2;和str无关 delete;而且最后销毁了
console.log(str);//abcd
// .length是系统自带的属性,字符串就有这个属性,只不过是对象字符串有这个属性
//如果要访问length new String('abcd').length 拿的是new String的字符串长度
console.log(str.length);//4
</script>
<!-- 例子 -->
<script>
var str="abc";
str+=1;//abc1 连着1 还是字符串
var test=typeof(str);//字符串 test=="string"
//typeof是返回这个值的类型 number string boolean undefined object function
if(test.length==6){
test.sign="typeof的返回结果可能为String"
//new String(test).sign='xxx'; delete销毁
}
//new String(test).sign
console.log(test.sign);
</script>
</body>
</html>
详解包装类:
<script>
/*
原始值是不能有属性和方法的,只是一个值,属性和方法只有对象才能有,对象包括对象自己,数组,function
*/
//原始值
var num=1;
// 构造函数123 变成了对象123,有自己属性和方法了
var num1=new Number(12)
</script>
原始值是不能有属性和方法,那么为什么下图有length属性,而且str.a不报错
因为经历了一个过程叫包装类
隐式发生了变化,这个隐式转换的过程叫做包装类
<script>
var num=4;
num.len=3;
//发生隐式转换 num不能加属性len,会新建一个数字对象的len new Number(4).len=3 不会保存然后delete销毁
// 这里打印num.len,又会重新new Number(4).len 此时是没有值的
console.log(num.len);//undefined
</script>
<script>
var str="abcd"
str.length=2;//自己是没有length的 new String('abcd').length=2; delete
console.log(str);//abcd
</script>
<script>
/*原始值没有方法和属性 比如string没有length属性,但是能查看它的length,因为js内部机制给它一个包装类
这个隐式过程就是包装类
*/
//例1
var str="abc";
//new String('abc').length
console.log(str.length);// console.log(new String('abc').length);
</script>
例题1:
答案"A" 写死在里面了,根本没用参数
例题2:
<script>
function Person(name, age, sex) {
var a = 0;
this.name = name;
this.age = age;
this.sex = sex;
function sss() {
a++;
console.log(a);
}
// 形成了闭包 函数sss拿着Person的劳动成果被保存出去了
this.say = sss;
}
var oPerson=new Person();
oPerson.say();
oPerson.say();
var oPerson1=new Person();//形成新的执行上下文,新的闭包
oPerson1.say();
</script>
例题3:请问x,y,z分别输出什么
<script>
var x=1,y=z=0;
function add(n){
return n=n+1;
}
y=add(x);
function add(n){
return n=n+3;
}
z=add(x)
</script>
有两个add函数,预编译的时候第二个就把第一个覆盖掉了,所以写x=1,y=4,z=4
<script>
//封装type
function type(target) {
//1.分两类 原始值(null判断不出,所以首先先判断null) 引用值
//2.区分引用值
//对象集合template
var template = {
"[object Array]": "array",
"[object Object]": "object",
//包装类 比如number对象new Number
"[object Number]": "number----object",
"[object String]": "string----object",
"[object Boolean]": "boolean----object",
}
if (target === 'null') {
return 'null'
}
if (typeof (target) == 'object') {
//对象
var str=Object.prototype.toString.call(target)
return template[str]
} else { //原始值
return typeof (target)
}
}
</script>