整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

第15节 Javascript引用类型-Web前端开

第15节 Javascript引用类型-Web前端开发-零点程序员-王唯

用类型的值(对象)是引用类型的实例;在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,它也常被称为类;尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构。

ECMAScript提供了很多原生引用类型,如Object,以便开发人员用以实现常见的计算任务。

引用类型的分类:

本地对象:独立于宿主环境的由ECMAScript实现提供的对象.如:Object、Function、Array等;

内置对象:由 ECMAScript实现提供的,独立于宿主环境的所有对象,如:Global和Math (本质上就是静态类,不需要创建对象,直接使用);

宿主对象:所有非本地对象都是宿主对象,即由ECMAScript实现的宿主环境提供的对象,如:所有BOM和DOM对象都是宿主对象;

对象是某个特定引用类型的实例,语法:

var person=new Object();

使用new操作符及一个构造函数,构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。

Object类型:

  • Object类型是ECMAScript中使用最多的一个类型;
  • Object类是所有类的基类;Object对象提供了JS其他对象的基本功能;
  • Object对象本身并不具备多少功能,在应用程序中一般用来存储和传输数据而言;

创建Object实例:

方式有两种:

使用new和Object的构造函数: var o=new Object(); 如:

var person=new Object();
person.name="wangwei";
person.age=18;

第二种方式:使得对象字面量表示法;

语法:var oObject={成员 : 值, 方法: function(){}},如:

var person={
    name:"wangwei",
    age:18
};

说明:花括号是表示对象的字面量,因为它出现在表达式上下文(expression context)中,这个表达式最终就是一个值,并且赋给了一个变量;

说明:字面量的属性采用的是键值对的定义方法,即:属性名:属性值,中间使用冒号分隔;多个属性,使用逗号分隔;

注,最后的属性的后面不加逗号了,但加逗号也没有问题。

属性名也可以使用字符串,如:

var person={
    "name":"wangwei",
    "my age":18,
    5:true
};

注:数值属性名会自动转换为字符串,但使用方式不同。

使用字面量语法时,可以留空花括号,则可以定义只包含默认属性和方法的空对象,与使用new Object()相同;

注:在通过字面量定义对象时,实际上不会调用Object构造函数;

并且,在实际场景中,对象字面量是向函数传递大量可选参数的首选方式,如:

function displayInfo(args){
    var output="";
    if(typeof args.name=="string"){
        output +="name:" + args.name + "\n";
    }
    if(typeof args.age=="number"){
        output +="age:" + args.age + "\n"; 
    }
    alert(output);
}
displayInfo({
    name:"wangwei",
    age:18
});
displayInfo({
    name:"wujing"
});

说明:函数dispalyInfo()接受一个名为args的参数;这个参数可能带有一个名为name或age的属性,也可能这两个属性都有或者都没有;在调有这个函数时,使用的是一个对象字面量来指定不同的数据;

注:这种传递参数的模式最适合需要向函数传入大量可选参数的情形;一般来说,命名参数虽然容易处理,但在有多个可选参数的情况下就会显示不够灵活;最好的做法是对那些必须值使用命名参数,而使用对象字面量来封装多个可选参数。

注:关于对象字面量语法,推荐只在考虑对象属性名的可读性时使用,因为这种语法要求的代码量少,而且能够给人封装数据的感觉;另外,选择字面量,还是因为字面量创建对象强调该对象仅是一个可变的hash映射,而不是从对象中提取的属性或方法。

为对象添加方法:

var wangwei={
    name: "wangwei",
    age: 18,
    sex: "男",
    smoke: function(smoke){
        console.log('I like smoking,it is ' + smoke);
    },
    drink: function(){
        console.log('I like to drink');
    }
}

Object对象属性:

Object对象的属性是动态的;

两种访问方式,一种是使用点表示法,这也是很多开发语言的通用的语法;第二种是使用方括号表示法,使用这种方法时,属性应以字符串的形式放在方括号中,如:

alert(person.name);
alert(person["name"]);

说明:从功能上看,这两种访问属性的方式没有任何区别;但使用方括号语法的主要优点是可以通过变量来访问属性,如:

var propertyName="name";
alert(person[propertyName]);

注:如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,就可以使用方括号表示法,如:

var person={
    "first name":"wangwei",
    8:true
};
alert(person["first name"]);
alert(person["8"]);

说明:因为属性名中是不能包含空格和数字的,所以使用此种方法来访问。

注:通常,除非必须使用变量来访问属性,否则建议使用点表示法。

动态添加属性和方法:

var stu={};
stu.name="wujing";
stu.age=38;
stu.sex=false;
function result() {
    console.log(stu.name + '年龄:' + stu.age);
}
stu.show=result
stu.show();

Object类及对象的属性和方法:

constructor属性:对创建对象的构造函数的引用; 如:

var obj=new Object();
console.log(obj.constructor);
var obj1=new obj.constructor;
console.log(obj1.constructor);
console.log(typeof obj1);

Object.prototype属性:对该对象的原型的引用;

console.log(Object.prototype);
function Person(){}
console.log(Person.prototype);

obj.hasOwnProperty(property)方法:判断该对象是否具有某个属性;

Object.prototype.isPrototypeOf(object)方法:判断该对象是否为另一个对象的原型;

obj.propertyIsEnumerable(property)方法:判断给定的属性是否可以用for...in...语句枚举;

obj.toString()方法:返回对象的原始字符串表示;

obj.valueOf()方法:返回最适合该对象的原始值;对于许多类,该方法返回的值都与toString()的返回值相同;

var obj=new Object();
obj.name="wangwei";
if(obj.hasOwnProperty("name")){
    console.log(obj.name);
}else{
    console.log("没有此属性");
}
if(obj.propertyIsEnumerable("name")){
    console.log("可枚举");
}else{
    console.log("不可枚举");
}
if(Object.prototype.isPrototypeOf(obj)){
    console.log("一样的原型链");
}else{
    console.log("不一样的原型链");
}
console.log(obj.toString());
console.log(obj.valueOf());

其它引用类型对象:

在 JS 中一切皆对象,除了Object这个顶级对象,有:String、Array、Date、RegExp等常规对象,还有Error错误对象等,特别是ES6,增加了大量的对象,比如:Map、Set,还有一些结构化、反射对象;同时还支持自定义对象。

var arr=new Array(1,2,3,4,5);
var str=new String("zeronetwork");
var d=new Date();
var pattern=new RegExp("/w/i");
// 自定义对象
function Person(name,age){
    this.name=name;
    this.age=age;
}
var p=new Person("wangwei",18);
console.log(p);

对象的废除:

一个对象不使用,应该废除,来释放内存,JS自带垃圾回收程序,其会自动判断对象的存活,进而释放掉没有活引用的对象。

强制销毁: oObject=null;对这个对象的引用就不存在了,下次运行收集程序时,该对象将被销毁。

必须把对象的所有引用都设为null,对象才会被清除;

var o=new Object();
var obj=o;
// delete o; // 删除不掉
o=null;
obj=null;
console.log(o);
console.log(obj);

基本类型与引用类型的值:

ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值;在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值;

基本类型值(原始值)是按值访问的,因为可以操作保存在变量中的实际的值;但原始值是不可变的,任何方法都无法更改一个原始值;如:

var str="zeronetwork";
console.log(str.toUpperCase());
console.log(str);  // zeronetwork 原始值字没有改变

原始值的比较是值的比较:只有在它们的值相等时它们才相等。

基本类型值复制:会在变量对象上创建一个新值,再把该值复制给新变量,如:

var num1=5;
var num2=num1;

引用类型值是保存在内存中的对象;与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间;在操作对象时,实际上是在操作对象的引用而不是实际的对象,因此,引用类型的值是按引用访问的。

引用类型(对象)的值是可变的,如:

var o={name:"wangwei",age:18};
console.log(o);
o.name="wujing";  // 通过修改属性值来更改对象
o.sex=false;  // 增加一个新属性
console.log(o);

var arr=[1,2,3,4,5];
arr[0]=18;    // 修改数组元素
arr[3]=20;
console.log(arr);

对象的比较并非值的比较,即使两个对象包含同样的属性及相同的值,它们也不相等;如:

var o={x:1}, p={x:1};
console.log(o==p);  // false
var a=[], b=[];
console.log(a==b);

对象的比较是引用的比较,当且仅当它们引用同一个基对象时,它们才相等,如引用类型复制,其会将存储在变量对象中的值复制一份放到为新变量分配的空间中,但不同的是,这个值实际上是一个指针,而这个指针指向存储在内存堆中的同个对象;复制之后,两个变量实际上将引用同一个对象;因此,改变其中一个变量,将影响到另一个变量,如:

var obj1=new Object();
var obj2=obj1;
obj1.name="wangwei";
alert(obj2.name);  // wangwei

引用类型的复制:

以上所说的是引用类型的浅复制,相对的,还有一个深复制,即得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素,如:

var a=["beijing","nanjing","anhui"];
var b=[];
for(var i=0;i<a.length;i++){
    b[i]=a[i];
}
console.log(b);

如果想比较两个单独的对象或者数组,则必须比较它们的属性或元素,如:

function equalArrays(a,b) {
    if(a.length !=b.length) return false;
    for(var i=0;i<length; i++){
        if(a[i] !==b[i]) return false;
    }
    return true;
}
var a=[1,2,3];
var b=[1,2,3,4];
console.log(equalArrays(a,b));

Web前端开发之Javascript-零点程序员-王唯

1)javascript的使用

HTML 中的脚本必须位于 <script> 与 </script> 标签之间。脚本可被放置在 HTML 页面的 <body> 和 <head> 部分中。

<script> 和 </script> 会告诉 JavaScript 在何处开始和结束。

<script> 和 </script> 之间的代码行包含了 JavaScript。

使用<script>的方式有两种,一种是直接在页面中嵌入Javascript代码,类是上边图片所示,另一种是包含外部JavaScript文件。包含在<script>内的javascript代码将被自上而下的依次解释。也可以把脚本保存到外部文件中。外部文件通常包含被多个网页使用的代码。外部 JavaScript 文件的文件扩展名是 .js。如需使用外部文件,请在 <script> 标签的 "src" 属性中设置该 .js 文件的路径。原理同css的引用类似。

(2)javascript标签的位置

按照传统做法,所有的<script>元素都应放在<head>标签里面,这样做的目的是把所有的外部文件(css文件和javascript文件)都放在相同的地方,便于管理。可是放在<head>中就意味着必须等所有的javascript代码 下载、解析、执行完之后,页面要呈现的内容才会被加载(浏览器在遇到<body>元素的时候才会加载呈现页面内容)。对于那些要执行很多javascript代码的页面来说,这无疑会导致浏览器在呈现页面时会出现很明显的延时,而延时期间页面一片空白,(等待javascript加载,未执行到<body>元素),这对于用户体验来说是无法容忍的,为避免这个问题,现代web程序一般都把javascript用于放到<body>元素中页面内容的最后面,即结束标签</body>之前。如上个程序代码所示。

(3)延迟脚本defer和异步脚本async

延迟脚本defer:这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在<script>元素中设置defer 属性,相当于告诉浏览器立即下载,但延迟执行。具体使用如下图所示:

异步脚本async:这个属性与 defer 属性类似,async 只适用于外部脚本文件,并告诉浏览器立即下载文件。但与 defer不同的是,标记为 async 的脚本不必等待其他脚本,也不必阻塞文档呈现,并且不保证按照指定它们的先后顺序执行。具体使用如下图所示:

(4)<noscript>元素

如果浏览器不支持 JavaScript ,或者被用户手动屏蔽时,对这种问题的最终解决方案就是创造一个<noscript>元素,用以在不支持 JavaScript 的浏览器中显示替代的内容。这个元素可以包含能够出现在文档<body>中的任何 HTML 元素——<script>元素除外。包含在<noscript>元素中的内容只有在下列情况下才会显示出来。具体的使用如下所示:

?

这个页面会在脚本无效的情况下向用户显示一条消息。而在启用了脚本的浏览器中,用户永远也不会看到它——尽管它是页面的一部分。

每日金句:我没有停止爱你,我只是决定不再表现出来。喜欢我的文章的小伙伴记得关注一下哦,每天将为你更新最新知识。

、JavaScript数据类型

(1)基本类型

5种基本类型:Undefined、Null、Boolean、Number、String

(2)引用类型

5种引用类型:Object、Array、Date、RepExp、Function

(3)基本类型与引用类型的异同:

1.保存方式

基本类型是按值访问的。引用类型的值是按引用访问的,引用类型的值是保存在内存中的对象,JavaScript在操作对象时,实际上是操作对象的引用而不是实际的对象。

2.复制变量值

复制基本类型值会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。复制引用类型值也会将存储在变量对象的值复制一份到新变量的空间,只是值的副本是一个指针,指向存储在堆中的一个对象。

3.参数传递

JavaScript中访问变量有按值和引用两种方式,而参数只能按值传递。

2、Object类型

对象是某个引用类型的实例。

大多数引用类型值都是Object类型的实例。

---创建Object实例的方法

(1) 使用new操作符后跟Object构造函数。

var person=new Object();
person.name="Alice";
person.age=23;
person[5]=true;

(2) 使用字面量表示法。

var person={
 "name" : "Alice",
 age : 23,
 5 : true
};

当属性名是字符串时,引号(单、双引号)可用也可不用。

对象字面量是向函数传递大量可选参数的首选方式。

---访问对象属性的方法

(1) 点表示法

alert(person.name);

(2)方括号表示法

alert(person["name"];

方括号表示法的优点:可以通过变量来访问属性。

var property="name";
alert(person[property];

若属性名中包含空格等或属性名是数值时,不能用点表示法,只能用方括号表示法。

alert(person[5]);

对前端的技术,架构技术感兴趣的同学关注我的头条号,并在后台私信发送关键字:“前端”即可获取免费的架构师学习资料

知识体系已整理好,欢迎免费领取。还有面试视频分享可以免费获取。关注我,可以获得没有的架构经验哦!!