搜索
首页web前端js教程JavaScript 面向对象精要(一)

数据类型

在JavaScript中,数据类型分为两类:

原始类型

保存一些简单数据,如true,5等。JavaScript共有5中原始类型:

  • boolean:布尔,值为true或false

  • number:数字,值为任何整型会浮点数

  • string:字符串,值为由单引号或双引号括出的单个字符或连续字符(JavaScript不区分字符类型)

  • null:空类型,其仅有一个值:nulll

  • undefined:未定义,其仅有一个值:undefined

var name = "Pomy";
var blog = "http://www.ido321.com";
var age = 22;
alert(typeof blog); //"string"
alert(typeof age); //"number"

原始类型的值是直接保存在变量中,并可以用 typeof 进行检测。但是typeof对null的检测是返回object,而不是返回null:

//弹出Not null
if(typeof null){
    alert("Not null");   
}else{
    alert("null");
}

所以检测null时,最好用全等于(===),其还能避免强制类型转换:

console.log("21" === 21);  //false
console.log("21" == 21);  //true
console.log(undefined == null);  //true
console.log(undefined === null);  //false

对于字符串、数字或者布尔值,其都有对应的方法,这些方法来自于对应的原始封装类型:String、Number和Boolean。原始封装类型将被自动创建。

var name = "Pomy";
var char = name.charAt(0);
console.log(char);  //"P"

在JavaScript引擎中发生的事情:

var name = "Pomy";
var temp = new String(name);
var char = temp.charAt(0);
temp = null;
console.log(char);  //"P"

字符串对象的引用在用完之后立即被销毁,所以不能给字符串添加属性,并且instanceof检测对应类型时均返回false:

var name = "Pomy";
name.age = 21;
console.log(name.age);   //undefined
console.log(name instanceof String);  //false

引用类型

保存为对象,实质是指向内存位置的引用,所以不在变量中保存对象。除了自定义的对象,JavaScript提供了6中内建类型:

  • Array:数组类型,以数字为索引的一组值的有序列表

  • Date:日期和时间类型

  • Error:运行期错误类型

  • Function:函数类型

  • Object:通用对象类型

  • RegExp:正则表达式类型

可以用new来实例化每一个对象,或者用字面量形式来创建对象:

var obj = new Object;
var own = {
            name:"Pomy",
            blog:"http://www.ido321.com",
            "my age":22
        };
console.log(own.blog);    //访问属性
console.log(own["my age"]); 
obj = null;  //解除引用

obj 并不包含对象实例,而是一个指向内存中实际对象所在位置的指针(或者说引用)。因为typeof对所有非函数的引用类型均返回object,所以需要用instanceof来检测引用类型。

函数

在JavaScript中,函数就是对象。使函数不同于其他对象的决定性特性是函数存在一个被称为[[Call]]的内部属性。内部属性无法通过代码访问而是定义了代码执行时的行为。

创建形式

1、函数声明:用function关键字,会被提升至上下文
2、函数表达式:不能被提升
3、实例化Function内建类型

sayHi();    //函数提升
function sayHi(){
    console.log("Hello");
}
//其他等效等效方式
/*
var sayHi = function(){
     console.log("Hello");
}
var sayHi = new Function(" console.log(\"Hello\");");
*/

参数

JavaScript函数的另外一个独特之处在于可以给函数传递任意数量的参数。函数参数被保存在arguments类数组对象中,其自动存在函数中,能通过数字索引来引用参数,但它不是数组实例:

alert(Array.isArray(arguments));   //false

类数组对象arguments 保存的是函数的实参,但并不会忽略形参。因而,arguments.length返回实参列表的长度,arguments.callee.length返回形参列表的长度。

function ref(value){
    return value;
}
console.log(ref("Hi"));
console.log(ref("Hi",22));
console.log(ref.length);  //1

函数中的this

关于this的问题,可参考此文:JavaScript中的this。

JavaScript提供了三个方法用于改变this的指向:call、apply和bind。三个函数的第一个参数都是指定this的值,其他参数均作为参数传递给函数。

对象

对象是一种引用类型,创建对象常见的两种方式:Object构造函数和对象字面量形式:

var per1 = {
    name:"Pomy",
    blog:"http://www.ido321.com"
};
var per2 = new Object;
per2.name = "不写代码的码农";

属性操作

在JavaScript中,可以随时为对象添加属性:

per1.age = 0;
per1.sayName = function(){
    alert(this.name);   //"Pomy"
}

因而,在检测对象属性是否存在时,常犯的一个错误是:

//结果是false
if(per1.age){
    alert(true)
}else{
    alert(false);
}

per1.age 是存在的,但是其值是0,所以不能满足if条件。if判断中的值是一个对象、非空字符串、非零数字或true时,判断会评估为真;而当值是一个null、undefined、0、false、NaN或空字符串时评估为假。

因而,检测属性是否存在时,有另外的两种方式:in和hasOwnProperty(),前者会检测原型属性和自有(实例)属性,后者只检测自有(实例)属性。

console.log("age" in per1);  //true
console.log(per1.hasOwnProperty("age"));  //true
console.log("toString" in per1);  //true
console.log(per1.hasOwnProperty("toString"));  //false

对象per1并没有定义toString,该属性继承于Object.prototype,所以in和hasOwnProperty()检测该属性时出现差异。如果只想判断一个对象属性是不是原型,可以利用如下方法:

function isPrototypeProperty(obj,name){
    return name in obj && !obj.hasOwnProperty(name);
}

若要删除一个属性,用delete操作符,用于删除自有属性,不能删除原型属性。

per1.toString = function(){
    console.log("per1对象");
};
console.log(per1.hasOwnProperty("toString"));   //true
per1.toString();   //"per1对象"
delete per1.toString;
console.log(per1.hasOwnProperty("toString"));   //false
console.log(per1.toString());  //[object Object]

有时需要枚举对象的可枚举属性,也有两种方式:for-in循环和Object.keys(),前者依旧会遍历出原型属性,后者只返回自有属性。所有可枚举属性的内部属性[[Enumerable]]的值均为true。

var per3 = {
    name:"Pomy",
    blog:"http://www.ido321.com",
    age:22,
    getAge:function(){
        return this.age;
    }
};

实际上,大部分原生属性的[[Enumerable]]的值均为false,即该属性不能枚举。可以通过propertyIsEnumerable()检测属性是否可以枚举:

console.log(per3.propertyIsEnumerable("name"));  //true
var pros = Object.keys(per3);  //返回可枚举属性的名字数组
console.log("length" in pros);  //true
console.log(pros.propertyIsEnumerable("length"));  //false

属性name是自定义的,可枚举;属性length是Array.prototype的内建属性,不可枚举。

属性类型

属性有两种类型:数据属性和访问器属性。二者均具有四个属性特征:

  • 数据属性:[[Enumerable]]、[[Configurable]]、[[Value]]和[[Writable]]

  • 访问器属性:[[Enumerable]]、[[Configurable]]、[[Get]]和[[Set]]

[[Enumerable]] :布尔值,属性是否可枚举,自定义属性默认是true。
[[Configurable]] :布尔值,属性是否可配置(可修改或可删除),自定义属性默认是true。它是不可逆的,即设置成false后,再设置成true会报错。
[[Value]]:保存属性的值。
[[Writable]]:布尔值,属性是否可写,所有属性默认可写。
[[Get]]:获取属性值。
[[Set]]:设置属性值。

ES 5提供了两个方法用于设置这些内部属性:
Object.defineProperty(obj,pro,desc_map) 和 Object.defineProperties(obj,pro_map)。利用这两个方法为per3添加一个属性和创建一个新对象per4:

Object.defineProperty(per3,"sex",{
    value:"male",
    enumerable:false,
    configurable:false, //属性不能删除和修改,该值也不能被设置成true
});
console.log(per3.sex);  //'male'
console.log(per3.propertyIsEnumerable("sex"));  //false
delete per3.sex;    //不能删除
per3.sex = "female"; //不能修改
console.log(per3.sex);  //'male'
Object.defineProperty(per3,"sex",{
    configurable:true, //报错
});
per4 = {};
Object.defineProperties(per4,{
    name:{
        value:"dwqs",
        writable:true
    },
    blog:{
        value:"http://blog.92fenxiang.com"
    },
    Name:{
        get:function(){
            return this.name;
        },
        set:function(value){
            this.name = value;
        },
        enumerable:true,
        configurable:true
    }
});
console.log(per4.name); //dwqs
per4.Name = "Pomy";
console.log(per4.Name); //Pomy

需要注意的是,通过这两种方式来定义新属性时,如果不指定特征值,则默认是false,也不能创建同时具有数据特征和访问器特征的属性。可以通过Object.getOwnPropertyDescriptor()方法来获取属性特征的描述,接受两个参数:对象和属性名。若属性存在,则返回属性描述对象。

var desc = Object.getOwnPropertyDescriptor(per4,"name");
console.log(desc.enumerable); //false
console.log(desc.configurable); //false
console.log(desc.writable); //true

根据属性的属性类型,返回的属性描述对象包含其对应的四个属性特征。

禁止修改对象

对象和属性一样具有指导其行为的内部特征。其中,[[Extensible]]是一个布尔值,指明改对象本身是否可以被修改([[Extensible]]值为true)。创建的对象默认都是可以扩展的,可以随时添加新的属性。
ES5提供了三种方式:

  • Object.preventExtensions(obj):创建不可扩展的obj对象,可以利用Object.isExtensible(obj)来检测obj是否可以扩展。严格模式下给不扩展对象添加属性会报错,非严格模式下则添加失败。

  • Object.seal(obj):封印对象,此时obj的属性变成只读,不能添加、改变或删除属性(所有属性都不可配置),其[[Extensible]]值为false,[[Configurable]]值为false。可以利用Object.isSealed(obj)来检测obj是否被封印。

  • Object.freeze(obj):冻结对象,不能在冻结对象上添加或删除属性,不能改变属性类型,也不能写入任何数据类型。可以利用Object.isFrozen(obj)来检测obj是否被冻结。 注意:冻结对象和封印对象均要在严格模式下使用。

"use strict";
var per5 = {
    name:"Pomy"
};
console.log(Object.isExtensible(per5));   //true
console.log(Object.isSealed(per5));         //false
console.log(Object.isFrozen(per5));       //false
Object.freeze(per5);
console.log(Object.isExtensible(per5));   //false
console.log(Object.isSealed(per5));       //true
console.log(Object.isFrozen(per5));       //true
per5.name="dwqs";
console.log(per5.name);   //"Pomy"
per5.Hi = function(){
    console.log("Hi");
};
console.log("Hi" in per5);  //false
delete per5.name;
console.log(per5.name);  //"Pomy"
var desc = Object.getOwnPropertyDescriptor(per5,"name");
console.log(desc.configurable);  //false
console.log(desc.writable);  //false

注意,禁止修改对象的三个方法只对对象的自有属性有效,对原型对象的属性无效,仍然可以在原型上添加或修改属性。

function Person(name){
    this.name = name;
}
var person1 = new Person("Pomy");
var person2 = new Person("dwqs");
Object.freeze(person1);
Person.prototype.Hi = function(){
    console.log("Hi");
};
person1.Hi();  //"Hi";
person2.Hi();  //"Hi";

以上就是JavaScript 面向对象精要(一) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器