构造函数内部原理
- 在函数体最前面隐式的加上this = {}
- 执行 thisxxx=xxx;
- 隐式的返回this
构造函数只要在函数前面加个new
function Student (name, age, sex) {
//第一步:隐式生成 var this = {};
//第二步:将this中赋值zhangsan、18、male
this.name = name;
this.age = age;
this.sex = sex;
this.grade = 2019;
//第三步:将this赋值好的东西返回
}
var student = new Student('zhangsan', 18, 'male');
console.log(student);
如果说你用了new,并且new的这个function中有return语句,那么它会自动把这个return语句忽略,并且return返回隐式生成的this变量
包装类
- new String();
- new Boolean();
- new Number();
function Person(name, height) {
// var this = {};
this.name = name;
this.height = height;
return 123;// 但凡用的是new,就不可能返回原始值,必定返回隐式生成的this变量
}
var person = new Person('xiaowang', 180);// 控制台发现还是原样输出
var person1 = new Person('xiaozhang', 175);
// 包装类
var num = 4;
num.len = 3;
// new Number(4).len = 3;---->delete 系统直接删除
//
// new Number(4).len 所以第二次查找这个len的时候就是undefined
console.log(num.len);
var str = "abc";
str += 1; // str = "abc" + 1 = "abc1"
var test = typeof (str); // test = "string"
if(test.length == 6) {
test.sign = "stypeof的返回结果可能为String"; // new String(test).sign = 'xxx'; --- delete
}
// new String(test).sign --> undefined
console.log(test.sign);
function Person (name, age, sex) {
var a = 0;
this.name = name;
this.age = age;
this.sex = sex;
function sss () {
a ++;
document.write(a);
}
this.say = sss;
}
// 闭包
var oPerson = new Person();// 生成执行上下文
oPerson.say();// 1
oPerson.say();// 2
var oPerson1 = new Person();// 生成另一个执行上下文
oPerson1.say();// 1
求字符串长度
var str = "asd加油";
function bytesLength (str) {
// var count = str.length;
// for(var i = 0; i < str.length; i++) {
// if(str.charCodeAt(i) > 255) {
// count++;
// }
// }
var count = 0;
for (var i = 0; i < str.length; i++) {
if(str.charCodeAt(i) > 255) {
count += 2;
} else {
count++;
}
}
return count;
}
console.log(bytesLength(str));
原型
- 定义:原型是 function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
- 利用原型特点和概念,可以提取共有属性。
- 对象如何查看原型一>隐式属性__proto__
- 对象如何查看对象的构造函数一> constructor
// Person.prototype -- 原型
// Person.prototype = {} 是祖先
Person.prototype.LastName = "xx";
Person.prototype.say = function () {
console.log('say')
}
function Person (name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
var person = new Person('xiaoming', 35, 'male');
// 打印出后,在person下的__proto__下有LastName
console.log(person);// {name: "xiaoming", age: 35, sex: "male"} person.LastName:xx
var person1 = new Person();
console.log(person1);// {name: undefined, age: undefined, sex: undefined} person.LastName:xx
Person.prototype.name = 'sunny';
function Person() {
// var this = {
// __proto__ : Person.prototype
// };
}
Person.prototype.name = 'cherry';
var person = new Person();// person.name : 'cherry'
Person.prototype.name = 'sunny';
function Person() {
// var this = {
// __proto__ : Person.prototype
// };
}
Person.prototype.name = {
};
var person = new Person();// person.name : 'cherry'
Person.prototype.name = 'sunny';
function Person() {
}
Person.prototype = {
name : 'cherry'
};// 执行顺序,先改了prototype,所以person中的name属性为'cherry'
var person = new Person();
// Person.prototype = {
// name : 'cherry'
// };// 把上面的一样的代码注释掉,把它移到下面来,就不一样了,首先,先执行new Person(),这样person指向了‘sunny’,后面不管怎么变,引用值还是‘sunny’
原型链
- 如何构成原型链?
因为每个对象和原型都有原型,对象的原型指向原型对象,
而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。 - 原型链上属性的增删改查
- 绝大多数对象的最终都会继承自Object. prototype
为什么说是绝大多数的对象呢,因为有个特例,create(null)
- Object create(原型)
方法的重写:
Person.prototype = {
// 重写了toString的方法
toString : function () {
return 'xxx';
}
}
function Person () {
}
var person = new Person();
JavaScript自带的方法也有重写的:
Object.prototype.toString
Number.prototype.toString
Array.prototype.toString
Boolean.prototype.toString
String.prototype.toString
Math.ceil() —>向上取整
Math.ceil(123.234)
124
Math.floor() —>向下取整
Math.floor(123.999999999)
123
Math.random() —>(0,1)之间的随机数
随机数两位小数:
for(var i = 0; i < 10; i++) {
var num = (Math.random() * 100).toFixed(2);// 因为JavaScript小数精度不太准,所以先乘一百,再取两位
console.log(num)
}
javaScript可正常计算的范围 小数点前十六位、后十六位
call/apply
作用,改变this指向
区别,后面传的参数形式不同。
call:
function Person (name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student (name, age, sex, tel, grade) {
Person.call(this, name, age, sex);// 利用Person的代码,实现自己的封装
//Person.apply(this, [name, age, sex]);
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny', 123, 'male', 139, 2019);
call 需要把实参按照形参的个数传进去
apply 需要传一个arguments