JavaScript的面向对象基础知识

wufei123 2024-06-02 阅读:9 评论:0
近年来,JavaScript 越来越受欢迎,部分原因是开发了一些库,使那些尚未完全掌握核心语言的人更容易创建 JavaScript 应用程序/效果。 虽然在过去,人们普遍认为 javascript 是一种基础语言,而且非常“草率”,没有...

近年来,JavaScript 越来越受欢迎,部分原因是开发了一些库,使那些尚未完全掌握核心语言的人更容易创建 JavaScript 应用程序/效果。

虽然在过去,人们普遍认为 javascript 是一种基础语言,而且非常“草率”,没有真正的基础;但现在情况已不再如此,尤其是随着大规模 web 应用程序和 json(javascript 对象表示法)等“适应”的引入。

JavaScript 可以拥有面向对象语言所提供的所有功能,尽管需要付出一些超出本文讨论范围的额外工作。

让我们创建一个对象 function myObject(){ };

恭喜,您刚刚创建了一个对象。创建 JavaScript 对象有两种方法:“构造函数”和“文字表示法”。上面的函数是一个构造函数,我将很快解释其中的区别,但在此之前,这是使用文字表示法的对象定义的样子。

var myObject = { };

文字是名称间距的首选选项,这样您的 JavaScript 代码就不会干扰(反之亦然)页面上运行的其他脚本,并且如果您将此对象用作单个对象并且不需要多个对象对象的实例,而如果您需要在创建对象之前执行一些初始工作,或者需要对象的多个实例(其中每个实例都可以在脚本的生命周期内更改),则首选构造函数类型表示法。让我们继续同时构建两个对象,以便我们可以观察差异。

定义方法和属性 构造函数版本: function myObject(){ this.iAm = 'an object'; this.whatAmI = function(){ alert('I am ' + this.iAm); }; }; 文字版本: var myObject = { iAm : 'an object', whatAmI : function(){ alert('I am ' + this.iAm); } }

对于每个对象,我们创建了一个属性“iAm”,其中包含一个字符串值,该字符串值在我们的对象方法“whatAmI”中使用,该方法会发出警报消息。

属性是在对象内部创建的变量,方法是在对象内部创建的函数。

现在可能是解释如何使用属性和方法的最佳时机(尽管如果您熟悉库,您可能已经这样做了)。

要使用属性,首先要输入它所属的对象 - 因此在本例中是 myObject - 然后要引用其内部属性,请先加上句号,然后输入属性名称,这样它最终看起来会像 myObject .iAm(这将返回“一个对象”)。

对于方法来说,除了执行方法之外,都是一样的,就像任何函数一样,必须在其后面加上括号;否则,您将只返回对函数的引用,而不是函数实际返回的内容。所以它看起来像 myObject.whatAmI() (这会提醒“我是一个对象”)。

现在来看看差异:
  • 构造函数对象的属性和方法是在其前面使用关键字“this”定义的,而字面版本则没有。
  • 在构造函数对象中,属性/方法的“值”在等号“=”之后定义,而在字面版本中,它们在冒号“:”之后定义。
  • 构造函数可以有(可选)分号“;”在每个属性/方法声明的末尾,而在字面版本中,如果您有多个属性或方法,则它们必须用逗号“,”分隔,并且它们后面不能有分号,否则 JavaScript 将返回错误。

这两种类型的对象声明的使用方式也存在差异。

要使用字面上标注的对象,您只需通过引用其变量名称来使用它,因此无论何时需要它,您都可以通过键入来调用它;

myObject.whatAmI();

使用构造函数,您需要首先实例化(创建对象的新实例);您可以通过输入来完成此操作;

var myNewObject = new myObject(); myNewObject.whatAmI(); 使用构造函数。

让我们使用之前的构造函数并在其基础上进行构建,以便在实例化它时执行一些基本(但动态)操作。

function myObject(){ this.iAm = 'an object'; this.whatAmI = function(){ alert('I am ' + this.iAm); }; };

就像任何 JavaScript 函数一样,我们可以在构造函数中使用参数;

function myObject(what){ this.iAm = what; this.whatAmI = function(language){ alert('I am ' + this.iAm + ' of the ' + language + ' language'); }; };

现在让我们实例化我们的对象并调用它的 WhatAmI 方法,同时填写所需的字段。

var myNewObject = new myObject('an object'); myNewObject.whatAmI('JavaScript');

这将警告“我是 JavaScript 语言的对象。”

实例化或不实例化

我之前提到过对象构造函数和对象文字之间的差异,当对对象文字进行更改时,它会影响整个脚本中的该对象,而当构造函数被实例化然后对其进行更改时实例,它不会影响该对象的任何其他实例。让我们尝试一个例子;

首先我们将创建一个对象文字;

var myObjectLiteral = { myProperty : 'this is a property' } //alert current myProperty alert(myObjectLiteral.myProperty); //this will alert 'this is a property' //change myProperty myObjectLiteral.myProperty = 'this is a new property'; //alert current myProperty alert(myObjectLiteral.myProperty); //this will alert 'this is a new property', as expected

即使您创建一个新变量并将其指向该对象,也会产生相同的效果。

var myObjectLiteral = { myProperty : 'this is a property' } //alert current myProperty alert(myObjectLiteral.myProperty); //this will alert 'this is a property' //define new variable with object as value var sameObject = myObjectLiteral; //change myProperty myObjectLiteral.myProperty = 'this is a new property'; //alert current myProperty alert(sameObject.myProperty); //this will still alert 'this is a new property'

现在让我们尝试使用构造函数进行类似的练习。

//this is one other way of creating a Constructor function var myObjectConstructor = function(){ this.myProperty = 'this is a property' } //instantiate our Constructor var constructorOne = new myObjectConstructor(); //instantiate a second instance of our Constructor var constructorTwo = new myObjectConstructor(); //alert current myProperty of constructorOne instance alert(constructorOne.myProperty); //this will alert 'this is a property' //alert current myProperty of constructorTwo instance alert(constructorTwo.myProperty); //this will alert 'this is a property'

正如预期的那样,两者都返回正确的值,但让我们更改其中一个实例的 myProperty。

//this is one other way of creating a Constructor function var myObjectConstructor = function(){ this.myProperty = 'this is a property' } //instantiate our Constructor var constructorOne = new myObjectConstructor(); //change myProperty of the first instance constructorOne.myProperty = 'this is a new property'; //instantiate a second instance of our Constructor var constructorTwo = new myObjectConstructor(); //alert current myProperty of constructorOne instance alert(constructorOne.myProperty); //this will alert 'this is a new property' //alert current myProperty of constructorTwo instance alert(constructorTwo.myProperty); //this will still alert 'this is a property'

从这个示例中可以看出,即使我们更改了 constructorOne 的属性,它也没有影响 myObjectConstructor,因此也没有影响 constructorTwo。即使在更改 constructorOne 的 myProperty 属性之前实例化了 constructorTwo,它仍然不会影响 constructorTwo 的 myProperty 属性,因为它是 JavaScript 内存中完全不同的对象实例。

那么您应该使用哪一个呢?好吧,这取决于情况,如果您的脚本只需要一个此类对象(正如您将在本文末尾的示例中看到的那样),则使用对象文字,但如果您需要一个对象的多个实例,其中每个实例彼此独立,并且根据其构造方式可以具有不同的属性或方法,然后使用构造函数。

这个和那个

在解释构造函数时,出现了很多“this”关键字,我想这是讨论作用域的更好时机!

现在您可能会问“您所说的范围是什么”? JavaScript 中的作用域是基于函数/对象的,因此这意味着如果您在函数之外,则无法使用在函数内部定义的变量(除非您使用闭包)。

然而,存在作用域链,这意味着另一个函数内的函数可以访问其父函数中定义的变量。让我们看一些示例代码。

<script type="text/javascript"> var var1 = 'this is global and is available to everyone'; function function1(){ var var2 = 'this is only available inside function1 and function2'; function function2(){ var var3 = 'this is only available inside function2'; } } </script>

正如你在这个例子中看到的, var1 是在全局对象中定义的,可用于所有函数和对象, var2 是在 function1 中定义的,可用于 function1 和 function2,但是如果你尝试引用从全局对象中获取它会给出错误“var2 未定义”,var3 只能由 function2 访问。

那么“this”指的是什么呢?在浏览器中,“this”引用窗口对象,因此从技术上讲,窗口是我们的全局对象。如果我们在一个对象内部,“this”将引用该对象本身,但是如果您在一个函数内部,这仍然会引用窗口对象,同样,如果您在一个对象内的方法内部,“ this' 将引用该对象。

由于我们的作用域链,如果我们位于子对象(对象内的对象)内部,“this”将引用子对象而不是父对象。

作为旁注,还值得补充的是,当使用 setInterval、setTimeout 和 eval 等函数时,当您通过其中之一执行函数或方法时,“this”指的是 window 对象,因为这些是 window 的方法,所以 setInterval() 和 window.setInterval() 是相同的。

好吧,现在我们已经解决了这个问题,让我们做一个真实的示例并创建一个表单验证对象!

现实世界的用法:表单验证对象

首先我必须向您介绍我们将创建的 addEvent 函数,它是 ECMAScript 的(Firefox、Safari 等)addEventListener() 函数和 Microsoft ActiveX Script 的 AttachEvent() 函数的组合。

function addEvent(to, type, fn){ if(document.addEventListener){ to.addEventListener(type, fn, false); } else if(document.attachEvent){ to.attachEvent('on'+type, fn); } else { to['on'+type] = fn; } };

这将创建一个具有三个参数的新函数,to 是我们将事件附加到的 DOM 对象,type 是事件类型,fn 是触发事件时运行的函数。它首先检查是否支持 addEventListener,如果支持,它将使用它,如果不支持,它将检查 AttachEvent,如果其他所有方法都失败,您可能正在使用 IE5 或同样过时的东西,因此我们将事件直接添加到其事件属性上(注意:第三个选项将覆盖可能已附加到事件属性的任何现有函数,而前两个选项会将其作为附加函数添加到其事件属性中)。

现在让我们设置我们的文档,使其与您开发 jQuery 内容时可能看到的类似。

在 jQuery 中你会有;

$(document).ready(function(){ //all our code that runs after the page is ready goes here });

使用我们的 addEvent 函数;

addEvent(window, 'load', function(){ //all our code that runs after the page is ready goes here });

现在我们的 Form 对象。

var Form = { validClass : 'valid', fname : { minLength : 1, maxLength : 15, fieldName : 'First Name' }, lname : { minLength : 1, maxLength : 25, fieldName : 'Last Name' }, validateLength : function(formEl, type){ if(formEl.value.length > type.maxLength || formEl.value.length < type.minLength ){ formEl.className = formEl.className.replace(' '+Form.validClass, ''); return false; } else { if(formEl.className.indexOf(' '+Form.validClass) == -1) formEl.className += ' '+Form.validClass; return true; } }, validateEmail : function(formEl){ var regEx = /^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/; var emailTest = regEx.test(formEl.value); if (emailTest) { if(formEl.className.indexOf(' '+Form.validClass) == -1) formEl.className += ' '+Form.validClass; return true; } else { formEl.className = formEl.className.replace(' '+Form.validClass, ''); return false; } }, getSubmit : function(formID){ var inputs = document.getElementById(formID).getElementsByTagName('input'); for(var i = 0; i < inputs.length; i++){ if(inputs[i].type == 'submit'){ return inputs[i]; } } return false; } };

所以这是非常基本的,但可以很容易地扩展。

为了解决这个问题,我们首先创建一个新属性,它只是“有效”CSS 类的字符串名称,当应用于表单字段时,会添加有效的效果,例如绿色边框。我们还定义了两个子对象,fname和lname,因此我们可以定义它们自己的属性,这些属性可以被其他地方的方法使用,这些属性是minLength,这是这些字段可以拥有的最小字符数, maxLength 是字段可以拥有的最大字符数,而 fieldName 实际上并没有被使用,但可以用于诸如在错误消息中使用用户友好的字符串识别字段之类的事情(例如“名字字段”)是必需的。')。

接下来我们创建一个 validateLength 方法,它接受两个参数: formEl 要验证的 DOM 元素和 type ,它引用要使用的子对象之一(即 fname 或 lname)。该函数检查字段的长度是否在 minLength 和 maxLength 范围之间,如果不是,那么我们从元素中删除有效类(如果存在)并返回 false,否则如果是,那么我们添加有效类并返回正确。

然后我们有一个 validateEmail 方法,它接受 DOM 元素作为参数,然后我们根据电子邮件类型正则表达式测试这个 DOM 元素值;如果通过,我们再次添加我们的类并返回 true,反之亦然。

最后我们有一个 getSubmit 方法。该方法获得表单的 id,然后循环遍历指定表单内的所有输入元素,以查找哪一个具有提交类型 (type="submit")。此方法的原因是返回提交按钮,以便我们可以禁用它,直到表单准备好提交。

让我们让这个验证器对象在真实的表单上工作。首先我们需要 HTML。

<body> <form id="ourForm"> <label>First Name</label><input type="text" /><br /> <label>Last Name</label><input type="text" /><br /> <label>Email</label><input type="text" /><br /> <input type="submit" value="submit" /> </form> </body>

现在让我们使用 JavaScript 访问这些输入对象,并在表单提交时验证它们。

addEvent(window, 'load', function(){ var ourForm = document.getElementById('ourForm'); var submit_button = Form.getSubmit('ourForm'); submit_button.disabled = 'disabled'; function checkForm(){ var inputs = ourForm.getElementsByTagName('input'); if(Form.validateLength(inputs[0], Form.fname)){ if(Form.validateLength(inputs[1], Form.lname)){ if(Form.validateEmail(inputs[2])){ submit_button.disabled = false; return true; } } } submit_button.disabled = 'disabled'; return false; }; checkForm(); addEvent(ourForm, 'keyup', checkForm); addEvent(ourForm, 'submit', checkForm); });

让我们分解一下这段代码。

我们将代码包装在 addEvent 函数中,以便在加载窗口时运行此脚本。首先,我们使用表单 ID 获取表单并将其放入名为 ourForm 的变量中,然后获取提交按钮(使用表单对象 getSubmit 方法)并将其放入名为 submit_button 的变量中,然后设置提交按钮禁用属性为“禁用”。

接下来我们定义一个 checkForm 函数。这会将表单字段内的所有输入存储为一个数组,并将其附加到一个名为..你猜对了的变量.. inputs!然后它定义了一些嵌套的 if 语句,这些语句根据我们的 Form 方法测试输入数组内的每个字段。这就是我们在方法中返回 true 或 false 的原因,因此如果它返回 true,我们将传递该 if 语句并继续执行下一个,但如果它返回 false,我们将退出 if 语句。

根据我们的函数定义,我们在页面最初加载时执行 checkForm 函数,并将该函数附加到 keyup 事件和提交事件。

您可能会问,如果我们禁用了提交按钮,为什么还要附加提交。好吧,如果您专注于输入字段并按下 Enter 键,它将尝试提交表单,我们需要对此进行测试,因此我们的 checkForm 函数返回 true(提交表单)或 false(不提交)形式)。

结论

因此,我们学习了如何在 JavaScript 中定义不同的对象类型并在其中创建属性和方法。我们还学习了一个漂亮的 addEvent 函数,并在基本的现实示例中使用我们的对象。

这就是 JavaScript 面向对象的基础知识。希望这可以让您开始构建自己的 JavaScript 库!如果您喜欢这篇文章并对其他 JavaScript 相关主题感兴趣,请将它们发布在评论中,我很乐意继续撰写它们。感谢您的阅读。

为什么不看看 CodeCanyon 上的 JavaScript 项目范围。您可以找到用于创建滑块、倒计时、加载器和上传器等的脚本。

JavaScript的面向对象基础知识

以上就是JavaScript的面向对象基础知识的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • 华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀

    华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀
    华为 mate 70 或将首发麒麟新款处理器,并将此前有博主爆料其性能跑分将突破110万,这意味着 mate 70 性能将重新夺回第一梯队。也因此,苹果 iphone 16 唯一能有一战之力的性能,也要被 mate 70 拉近不少了。 据悉,华为 Mate 70 性能会大幅提升,并且销量相比 Mate 60 预计增长40% - 50%,且备货充足。如果 iPhone 16 发售日期与 Mate 70 重合,销量很可能被瞬间抢购。 不过,iPhone 16 还有一个阵地暂时难...
  • 酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元

    酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元
    本站 5 月 16 日消息,酷凛 id-cooling 近日推出霜界 240/360 一体式水冷散热器,采用黑色无光低调设计,分别定价 239/279 元。 本站整理霜界 240/360 散热器规格如下: 酷凛宣称这两款水冷散热器搭载“自研新 V7 水泵”,采用三相六极马达和改进的铜底方案,缩短了水流路径,相较上代水泵进一步提升解热能力。 霜界 240/360 散热器的水泵为定速 2800 RPM 设计,噪声 28db (A)。 两款一体式水冷散热器采用 27mm 厚冷排,...
  • 惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起

    惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起
    本站 5 月 14 日消息,继上线官网后,新款惠普战 99 商用笔记本现已上架,搭载酷睿 ultra / 锐龙 8040处理器,最高可选英伟达rtx 3000 ada 独立显卡,售价 4999 元起。 战 99 锐龙版 R7-8845HS / 16GB / 1TB:4999 元 R7-8845HS / 32GB / 1TB:5299 元 R7-8845HS / RTX 4050 / 32GB / 1TB:7299 元 R7 Pro-8845HS / RTX 2000 Ada...
  • python中def什么意思

    python中def什么意思
    python 中,def 关键字用于定义函数,这些函数是代码块,执行特定任务。函数语法为 def (参数列表)。函数可以通过其名字和圆括号调用。函数可以接受参数作为输入,并在函数体中使用参数名访问。函数可以使用 return 语句返回一个值,它将成为函数调用的结果。 Python 中 def 关键字 在 Python 中,def 关键字用于定义函数。函数是代码块,旨在执行特定任务。 语法 def 函数定义的语法如下: def (参数列表): # 函数体 示例 定义...
  • python中int函数的用法

    python中int函数的用法
    int() 函数将值转换为整数,支持多种类型(字符串、字节、浮点数),默认进制为 10。可以指定进制数范围在 2-36。int() 返回 int 类型的转换结果,丢弃小数点。例如,将字符串 "42" 转换为整数为 42,将浮点数 3.14 转换为整数为 3。 Python 中的 int() 函数 int() 函数用于将各种类型的值转换为整数。它接受任何可以解释为整数的值作为输入,包括字符串、字节、浮点数和十六进制表示。 用法 int(object, base=10) 其中...