var obj = {} ----plainObject 对象字面量/对象直接量
构造函数
var obj = new Object();
function Student(name){
this.name = name;
this.grade = 2016;
this.read = function(){...}
}
var studentHo = new Student('HoYuu');
String()
Number()
Boolean()
prototype -----是祖先,值是一个对象
自身就有,初始为空对象,可手动添加属性
构造函数上的一个属性
eg.
Student.prototype.school = 'tust';
function Student(name){
this.name = name;
this.grade = 2016;
this.read = function(){...}
}
var studentHo = new Student('HoYuu');
studentHo.school;
构造函数,原型中自带的属性之一
对象身上的
自带属性之一,也是原型(prototype是标准的,__proto__是非标准的——浏览器自己部署的)
eg.
Student 中
this = {
__proto__:Student.prototype
}
Student.prototype 中
__proto__:object
Object.creat(原型)
绝大多数对象的最终都会继承自Object.prototype
例外:Object.creat(null);
JS 精度略微不准:
可正常计算的范围:小数点前16位,后16位
输出随机数
for(var i = 0; i < 10; i++){
// toFix(n) , 保留n位小数
// 向上取整ceil , 向下取整floor
var num = Math.floor(Math.random()*100);
console.log(num);
}
作用:改变this指向
区别:后面传的参数形式不同
function Person(name,age){
this.name = name;
this.age = age;
}
var obj = {}
Person.call(obj,'小明',20);
// this ----> obj
obj.name;// 小明
obj.age;// 20
function Person(name,sex,age)
{
this.name = name;
this.sex = sex;
this.age = age;
}
function Student(name,sex,age,tel,grade){
Person.call(this,name,sex,age);
// Person.apply(this,[name,sex,age]);
this.tel = tel;
this.grade = grade;
}
var student = new Student('大富','男',18,13536,2018);
传统形式 ------原型链
缺点:继承了过多没用的属性
借用构造函数 -------call/apply
不能继承借用构造函数的原型
每次构造函数都要多走一个函数
共享原型
Son.prototype = Father.prototype;
不能随便改动自己的原型
Son往原型上添加信息,Father的原型也会有同样改变
function F(){}
F.prototype = Father.protoytpe;
Son.prototype = new F();
封装成函数
function inherit(Target,Origin){
function F(){};
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constuctor = Target;
Target.prototype.uber = Origin.prototype;//可不写,知道真正继承自谁
}
inherit(Son,Father);
var son = new Son();
更好的写法:
var inherit = (function (){
function F(){};
return function(Target,Origin){
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constuctor = Target;
Target.prototype.uber = Origin.prototype;
}
}());
管理变量,防止污染全局,适用于模块化开发
更简洁:使用闭包-----立即执行函数,返回函数
for in
会把原型的属性也打印出来
var obj = {
name : 'zfx',
age : 18,
grade : 'perfect',
face : 100
}
// 打印出对象的属性
for(var prop in obj){
console.log(prop);
// 或者 console.log(obj[prop]);
// 不能写成: obj.prop
}
if(obj.hasOwnProperty()){
console.log(obj[prop]);
}
in
!!! instanceof
A instanceof B
实际:看A对象的原型链上,是否有B的原型
有一个变量,可能是 数组 或 对象,判断是哪种
var arr = [] || {};
arr.constructor();
数组返回 Array()
对象返回 Object()
arr instanceof Array
数组返回 true
对象返回 false
Object.propeotype.toString.call(arr);
数组返回 [Object Array]
对象返回 [Object Object]
var name = '222';
var a = {
name : '111',
say : function (){
console.log(this.name);
}
}
var fun = a.say;
fun(); //222
a.say(); //111
var b = {
name : '333',
say : function (fun){
fun();
}
}
b.say(a.say); //222
b.say = a.say;
b.say(); //333
// 计算n的阶乘
var num = (function(n){
if(n == 1){
return 1;
}else return n * arguments.callee(n-1);
}(10))
function demo(){
test();
}
function test(){
console.log(test.caller);
}
demo();
// 控制台结果:demo...
var obj = {
name : 'loly',
height : 80,
card : ['hello','vivi']
}
var obj1 = {};
function clone (Origin, Target){
Target = Target || {};//当没有传第二个参数时,自创Target为空对象
for(var prop in Origin){
Target[prop] = Origin[prop];
}
}
clone(boj, obj1);
// obj1 其他属性值改变, obj 对应的不会改变;
// 但obj1 改变 card(数组)的值, obj 对应的也会改变
要求 obj1 无论改变什么值,都不会影响 obj
function deepClone(origin, target) {
target = target || {};
var prop,
arrStr = Object.prototype.toString,
toStr = '[object Array]';
for (prop in origin) {
if (origin.hasOwnProperty(prop)) {
// 只克隆对象自身拥有的属性,而不克隆其原型链上的
if (prop !== null && typeof (origin[prop]) == 'object') {
//当属性值不为null 且 属性值为引用值
if (arrStr.call(prop) == 'toStr') {
//当引用值为数组
target[prop] = [];
} else {
// 当引用值为对象
target[prop] = {};
}
// 递归
deepClone(origin[prop], target[prop]);
} else {
//当属性值为原始值
target[prop] = origin[prop];
}
}
}
return target;
}
deepClone(obj, obj1);
?:
条件判断? 是 :否 且返回值
var num = 1 > 0 ? 6+5 : 1-5;
有var的属性,是不可配置属性,不能delete
var num = 1223;
delete window.num; ----false