• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

零基础快速掌握JavaScript(3)js工作原理、对象

互联网 diligentman 2小时前 2次浏览

目录

上篇回顾

 一.js工作原理

1.设计初衷

2.单线程

3.异步

4.JS同步模式

 5.异步模式

 6.js垃圾回收机制

垃圾回收原因:

 解决内存泄漏的方法:

回收方式:

变量被视为垃圾的情况:

变量不被视为垃圾的情况:

二.对象

1.如何创建对象

1.字面量方式

2.构造函数方式

2.调用对象属性及方法

3.如何删除、添加、修改对象属性

4.如何遍历对象

5.对象类型转换

1.转为布尔类型

2.转为字符串类型

3.转为数值类型

4.重写toString方法与valueOf方法

6.在对象中的检测属性和方法

1.检测属性方法

2.检测对象是否在同一个原型链中

7.如何设置对象原始属性

1.设置某一对象的某一原始属性:Object.definePropertype()

2.一次设置一个对象的多个原始属性 Object.definePropertys()

3.查看对象某个属性的原始属性 Object.getOwnPropertyDescriptor()

8.构造器属性

9.值传递与引用传递(址传递)

10.对象序列化

1. 常规转换

2. 转换为json字符串

3. 转换为查询字符串


上篇回顾

零基础快速掌握JavaScript(3)js工作原理、对象

 零基础快速掌握JavaScript(3)js工作原理、对象

 一.js工作原理

1.设计初衷

js设计初衷为运行在浏览器端的脚本语言(主要就是操作dom

2.单线程

(若为多线程可能会为多个线程同时操作一个dom,导致bug频出)

执行的代码线程只有一个,任务量大执行任务需要排队,如果某一个任务执行时间很长,那便会出现阻塞的问题,会导致用户体验差 ,为了解决阻塞问题,就出现了异步的方式。

3.异步

一般有两种情况使用异步:

setTimeOut(倒计时)某些功能需要等待多少时间后执行;

Ajax请求 通常也视为异步(请求数据时,数据返回时间不确定);

4.JS同步模式

零基础快速掌握JavaScript(3)js工作原理、对象

 5.异步模式

零基础快速掌握JavaScript(3)js工作原理、对象

 6.js垃圾回收机制

垃圾回收原因

        内存中存在一些不再需要的变量,这些 变量会产生垃圾,如果不处理便会一直积压,会影响到用户体验,也会造成内存泄露,所以为了解决内存泄露,js就有了垃圾回收机制

 解决内存泄漏的方法

        间隔的不定期的寻找不再使用的变量并释放

回收方式

        标记清除(在变量生成时会打上标记,之后会观察变量是否需要,不需要时便会清除)

        引用技术

变量被视为垃圾的情况:

                 没有被引用;多个对象相互引用形成闭环

变量不被视为垃圾的情况:

                 有具体的引用关系(闭包:函数内部含有函数,内部函数引用外部变量

                 全局变量(随时会被使用,时刻待命

function test(){
    //在函数功能体中每一次执行完毕后,不被引用的变量会被销毁
   var num = 0;
   console.log(++num);
}
test();//1
test();//1
test();//1

二.对象

 js中万物皆为对象

字符串,布尔,数值皆为对象,它们都可以调用对象,即调用对象原始方法toString(通过原型链进行调用),其实是在我们Object对象中,它们之所以可以调用对象,是因为它们三种类型也是通过对象方法创建的。null、undefined比较特殊,不能调用原始方法toString

var str = 'xioaming';
str.toStrong();//可以直接调用是因为在调用时js会自动进行装箱的操作,
//装箱:即自动使用包装器String()将str转换为对象,然后再使用tostring方法调用
//装箱后便会通过拆箱来返回字符串
var str1=new String('xioahong');//返回一个对象类型的字符串
console.log(str,str1);//xiaoming   [String: 'xioahong']

1.如何创建对象

1.字面量方式

var stu = {//通过大括号来创建,括号内放置对象的描述(属性)和功能(方法)
        name:'xiaoming',
        height:180,
        weight:60,
        cook(){//方法,可以有多个
            console.log(this.name+'会做饭');
            //通过this指向本对象,加点属性名即可调用对象的某个属性
        },
}

2.构造函数方式

使用Object或者使用自定义构造函数来初始化对象(例如Student)

var stu2 = new Object();
stu2.name="xiaohong";
stu2.height=160;
stu2.weight=50;
stu2.sayHellow=function(){
    console.log(this.name+' say hello')
}
stu2.sayHellow();//xiaohong say hello

2.调用对象属性及方法

访问对象属性

点表示法,右侧必须是以属性名称命名的简单标识符

person.name

中括号表示法

中括号中必须是一个计算结果为字符串的表达式,可以通过变量访问属性,如果属性名中含语法错误的字符,或者属性名使用的是关键字或保留字,可以使用中括号

person["first name"]

//访问属性的方式
console.log(stu.name);
console.log(stu['name'])
//[]内必须为字符串,不加‘’时会被视为变量,然后全局查找这个变量

//方法调用
stu.cook();

3.如何删除、添加、修改对象属性

删除属性只能删除自定义属性,不能删除继承过来的属性

当添加对象中没有的属性时为新增属性,当对象有时,便为修改属性

//删除
delete stu.height;
//新增
stu.height='180';
//修改
stu.height='170';

4.如何遍历对象

/对象如何进行for  in 遍历
//能被for in语句打印的属性称为可枚举属性(默认情况下自定义的属性都是可枚举的)

//不可枚举属性:js中基本包装类型的原型属性是不可枚举的,如Object, Array, Number等
// var num = new Number();
//     for(var pro in num) {
//         console.log("num." + pro + " = " + num[pro]);
//     }
// 它的输出结果会是空。这是因为Number中内置的属性是不可枚举的,所以不能被for…in访问到。

for (k in stu){//in的左侧为属性的键,右边为需要遍历的对象,里面有多少属性就打印多少次
    console.log(stu.k);//调用失败,不加括号被认为是变量
    console.log(stu[k]);//调用成功
//代表对象属性的键,即name,weight,height等属性名的统称
//键的右侧即为值,所以name:‘xm’称为键值对
}

5.对象类型转换

1.转为布尔类型

// Object类型到Boolean类型
//空对象也可以直接转
var obj={};
console.log(Boolean(obj));//true

// 除了空引用(null)会转换为false,其他都被转换为true

var obj = {
	name:"briup",
	age:12
};
console.log(Boolean(obj));//true

2.转为字符串类型

// Object类型转换为String类型
console.log(obj.toString());//[object Object]
console.log(String(obj));//[object Object]

3.转为数值类型

// Object类型转换为Number类型
//如果没有重写valueOf,转数值类型会返回NaN,若重写则优先调用valueOf
var obj = {
	name:"briup",
	age:12,}
console.log(Number(obj));//NaN

4.重写toString方法与valueOf方法

//重写一个对象toString();
var obj = {
	name:"briup",
	age:12,
	toString:function(){
	return this.name+"--"+this.age;
    }
};
console.log(obj.toString());//briup--12
console.log(String(obj));//briup--12
//重写toString方法后,包装器会自动调用toString,然后获取toString的值并返回
//所以在调用方法时要注意是否有重写toString方法


// valueOf()   toString()
/*
1.两个方法都为对象的原始方法
2.valueOf为对象原始值,通常不会显示的调用,通常由js自动在后台调用
3.toString本身作用就是做字符串的转换,也会进行自动调用
4.如果只重写了valueOf()或者toString()方法,
无论是运算还是显示都调用该方法,并将返回值用Number()转换。
5.如果两个方法都重写了,运算时优先调用valueOf(),
并将返回值用Number()转换。进行显示时优先调用toString()
6.如果两个方法都没有重写,则返回NaN
*/ 

var obj = {
	name:"briup",
	age:12,
	toString:function(){
		return "100";
	},
	valueOf:function(){
		return 10;
	}
};

console.log(obj+2);//12
console.log(Number(obj));//10

var obj = {
	name:"briup",
	age:12,
	toString:function(){
		return "100";
	},
}
console.log(obj+2);//1002 字符串类型的数值
console.log(Number(obj));//100

//可以通过valueOf实现累加,每次调用obj时,valueOf都会被调用
//因为num在valueOf中被引用,所以不会被垃圾回收机制回收
var obj = {
    num:1,
    valueOf:function(){
        return this.num++
    }
}
console.log(obj==1);//true
console.log(obj==2);//true
console.log(obj==3);//true

6.在对象中的检测属性和方法

1.检测属性方法

//检测属性方法
//in 关键词 检测某个属性是否是某个对象自有属性或者继承属性,返回布尔类型(true或false)
//hasOwnProperty(PropertyName)   检测某个属性是否是某个对象自有属性,继承的属性不行
//propertyIsEnumerable()   检测某个属性是否是某个对象自有属性,且可枚举
var obj  = {
    name:'xm'
}
console.log('name' in obj);//true
console.log(obj.hasOwnProperty('name'));//true
console.log(obj.propertyIsEnumerable('name'));//true
console.log(obj.hasOwnProperty('hhh'));//false 没有的就返回false

2.检测对象是否在同一个原型链中

原型链是一种关系,是实例对象和原型对象之间的关系,这种关系是通过原型(proto)来联系的。

//检测对象是否在同一个原型链中(同一个家族,有层次,逐级向下)
//isPrototypeOf(object) 检测一个对象是否存在与另一个对象的原型链上,
//在就返回true反之false(原型的指向) 检查传入的对象的原型 
//instanceof  检测一个对象是否是某个构造函数的实例(new)
var str = new String('hh');
console.log(str instanceof String);//true
console.log(str instanceof Object);//true 沿着原型链一直向上找

function Animal(){}//自定义一个函数
var dog1 = new Animal();
console.log(dog1 instanceof Animal);//true
console.log(dog1 instanceof Object);//true 无论是什么对象它的顶层都是object

console.log(Animal.prototype.isPrototypeOf(dog1));//true
console.log(Object.prototype.isPrototypeOf(dog1));//true
function Dog(){}
var dog2 = new Dog();
console.log(Animal.prototype.isPrototypeOf(dog2));//false 不在一条原型链中
Dog.prototype = new Animal();//原型链继承,将子类构造函数的原型属性,指向父类的实例
//new animal相当于构造函数的父亲,而animal相当于他的家族,
//之所以指向他而不是指向animal,是因为生它的是他的父亲而不是家族
var dog2 = new Dog();
console.log(Animal.prototype.isPrototypeOf(dog2));//true

7.如何设置对象原始属性

1.设置某一对象的某一原始属性:Object.definePropertype()

//设置一个对象的原始属性
//Object.defineProperty 只能设置某一个对象中的某一个属性的原始属性
var obj = {
	name:'xm',
	age:12,
	sex:'nan'
}
Object.defineProperty(obj,'name',{
	configurable:false,//原始属性 默认可以被删除,false即不可被删除
	enumerable:false,//原始属性  默认可以被枚举  false即不可以枚举
	writable:false,//原始属性   默认可以被修改   false即不可以修改
	value:'lisi'
})
console.log(obj);
console.log(obj.name);//可以调用,但因为不可枚举,所以在node中不展示
delete obj.name;//不可被删除
obj.name = 'xm';//不可以修改
console.log(obj.name);//{ age: 12, sex: 'nan' } lisi
for(var k in obj){
	console.log(obj[k]);
}//不可枚举

2.一次设置一个对象的多个原始属性 Object.definePropertys()

//一次设置对象的多个原始属性
//Object.defineProperties
Object.defineProperties(obj,{
	age:{
		configurable:false
	},
	sex:{
		configurable:false
	}
})

3.查看对象某个属性的原始属性 Object.getOwnPropertyDescriptor()

//想知道某个属性的原始属性 Object.getOwnPropertyDescriptor()
var res = Object.getOwnPropertyDescriptor(obj,'name');
console.log(res);
// {value: 'lisi',writable: false,enumerable: false,configurable: false }

8.构造器属性

可以重写自定义属性set与get方法

在对象中,我们可能会设置一些比较奇怪的属性 _num、这种属性我们称为构造器函数,这种属性我们不希望直接通过外部访问 obj_num,我们希望自己去控制这个属性的访问逻辑 ,即obj_num可以访问到,并且会对它进行一些逻辑改变

var obj = {
	_num:0
}
//obj_num可以访问到,且会返回数字:0
//构造器属性:可以重写自定义属性set与get方法
Object.defineProperty(obj,'num',{
//当我们没有设置这两个属性时。默认是隐式调用,如果设置了则会调用你设置的方法
	set(num){
		this._num = num
	},//在num的值被设置时,调用
	get(){
		return '数字:'+this._num
	}//在num的值被获取时,调用
})

console.log(obj.num);//数字:0
obj.num=5;
console.log(obj.num);//数字:5

9.值传递与引用传递(址传递)

基本数据类型的变量:

可以直接操作保存在变量中的实际的值

参数传递的时候传递的是实际值

引用数据类型的变量:

不能直接操作对象的内存空间,实际上是在操作对象的引用。可以为引用类型变量添加属性和方法,也可以改变和删除其属性和方法。

参数传递的时候传递的是引用地址。

10.对象序列化

对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数,RegExp,Error对象,undefined值不能序列化和反序列化

JSON.stringify(obj) 将对象序列化为Json字符串,只能序列化对象可枚举的自有属性

JSON.parse(jsonStr) 反序列化

1. 常规转换

   obj.toString()

2. 转换为json字符串

  JSON.stringify(obj)

//用户输入信息
var user_info = {
	username:'zs',
	password:'123321',
	age:'13'
}
//登录接口需要json格式的数据
//JSON.stringify(obj)
var j_str = JSON.stringify(user_info);//{"username":"zs","password":"123321","age":"13"}
console.log(j_str);//{"username":"zs","password":"123321","age":"13"}
// 返回json字符串,是一种有规则的字符串
//得到json字符串如何转回对象
var user_info2 = JSON.parse(j_str)//反序列化
console.log(user_info2);//{ username: 'zs', password: '123321', age: '13' }
console.log(user_info2.username);//zs

//自定义json字符串反序列化为对象
var str = '{ "username": "zs"," password": "123321", "age": 13 }';
var str_obj = JSON.parse(str);
console.log(str_obj.age);//zs 13

3. 转换为查询字符串

  var qs = require('querystring')

  qs.stringify(obj)


程序员灯塔
转载请注明原文链接:零基础快速掌握JavaScript(3)js工作原理、对象
喜欢 (0)