前端及开发文章及欣赏

label和span标签设置宽度width无效的解决办法

前端达人

如何用CSS使label标签等宽?

<div><label>密码</label><input type="password" /></div>
<div><label>确认密码</label><input type="password" /></div>
如何对齐呢?加空格的方法不好哦。(因为label中的字数不一样,所以页面显示效果不对齐)
问题原因及解决办法:

label默认为内联元素,元素前后没有换行符,并且不可以设置宽度。

如果要为label设置宽度,则需要改变label的display属性,使其变为一个块级元素。

方法如下:

1.增加inline-block属性值,将label标签变为行内块元素(css2.1新增)

     {display:inline-block;}

2.增加width属性,如将宽度设置为100px
    label{width:100px;display:inline-block;}

3.添加好后页面上所有的label标签会变为100pxv



JavaScript中的混淆器

随着 AJAX 和富界面技术的发展,Javascript 在 Web 应用上的重要性越来越高,Javascript 代码的复杂性、功能和技术含量也越来越高,对Javascript 代码保护的需要也越来越迫切。



压缩 compress: 去掉空格,换行,注释等,格式紧凑,节约存储空间。



混淆 obfuscate/garble:替换变量名或方法名,让js不容易看懂。也做到了压缩的效果。



加密 encrypt:一般用eval方法加密,效果与混淆相似。也做到了压缩的效果。



我们可以通过工具进行混淆,通过工具也是目前最好的方式。推荐一个很好的混淆工具: JSObfuscator By Unest


20200321102359879.png


————————————————

版权声明:本文为CSDN博主「刘亦枫」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/liuyifeng0000/article/details/105004732




"从客户端中检测到有潜在危险的 Request.Form 值"的解决方案汇总

seo达人

在一个asp.net 的项目中,前端通过ajax将富文本中的文字内容post到服务端的一个ashx中,在ashx中尝试读取参数值时,

结果报错:“从客户端中检测到有潜在危险的 Request.Form 值”

#事故分析
由于在asp.net中,Request提交时出现有html代码字符串时,程序系统会认为其具有潜在危险的值。会报出“从客户端 中检测到有潜在危险的Request.Form值”这样的Error。

而富文本中的内容是包含html代码的,所以...

#解决方案:
1、前端对富文本字符串进行encodeURI编码,服务端进行HttpUtility.UrlDecode解码操作;
前端代码:

var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
    $(function() {
        $.ajax({
            type: "post",
            url: "TestHandle.ashx",
            data: { Title: 'jack', Content: encodeURI(str) },
            success: function (data) {
                $("#div").html(data);
            }
        });
    });
后端代码:

    public void ProcessRequest(HttpContext context)
    {
        string str = context.Request["content"];
        string content = HttpUtility.UrlDecode(str);
        context.Response.ContentType = "text/plain";
        context.Response.Write(content);
    }
效果图:

2、前端不以form的方式提交,直接以json方式提交,服务端从request的body中读取数据,然后反序列化,得到信息;
前端代码:

    var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
    var temp = { Title: 'jack', Content: str };
    $.ajax({
        type: "post",
        url: "TestHandle.ashx",
        contentType:"application/json;charset=utf-8",
        data: JSON.stringify(temp),
        success: function (data) {
            $("#div").html(data);
        }
    });
后端代码:

    string bodyText;
    using (var bodyReader = new System.IO.StreamReader(context.Request.InputStream))
    {
        bodyText = bodyReader.ReadToEnd();
    }
    dynamic bodyObj = JsonConvert.DeserializeObject(bodyText);
 
    context.Response.ContentType = "text/plain";
    context.Response.Write(bodyObj.Content);
效果图:

#其他场景的解决方案:
1、aspx页面,当前页面进行form提交
打开当前.aspx页面,页头加上代码:validateRequest=”false”,如:

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="false" CodeFile="default.aspx.cs" Inherits="default" %>
该方法不推荐,还有一种修改web.config配置文件的方法,强烈不推荐,就不写在这里了;

2、在ASP.NET MVC中的解决方案
1)、针对某个实体类的单个字段设置 [AllowHtml] ,这样提交的时候,系统就会放过该字段。

2)、前端代码:

    var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
    $(function () {
        $.ajax({
            type: "post",
            url: "Home/Test",
            data: { Title: 'jack', Content: str },
            success: function (data) {
                $("#div").html(data.ok);
            }
        });
    });
3)、后端代码:

    public class NewInfo
    {
        public string Title { get; set; }
        [AllowHtml]
        public string Content { get; set; }
    }
 #写在最后
 该文只是浅显的总结一下,其中涉及的xss方面,没有详细考虑,欢迎指正!

JavaScript中Array数组的some()函数的详解

seo达人

前言

开发中,经常会用到js的Array数组的各种迭代函数map(),filter(),some(),every(),forEach(),find() findIndex(),也是在ES6中新增一些遍历函数。同样是不是也是一道面试题,说说ES6新增的一些新特性????



✍开始正文some()函数



✍一、对some()函数的定义:



some():用于检测数组中的元素是否满足指定条件(函数提供);

some()方法会依次执行数组中的每一个元素:



如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测。

如果没有满足条件的元素,则返回false。

注意:



some()不会对空数组进行检测。

some() 不会改变原始数组。

✍二、浏览器支持

表格中的数字表示支持该方法的第一个浏览器的版本号。



✍三、语法



array.some(function(currentValue,index,arr),thisValue)

1

参数说明:



✍三、示例



<script>

var ages = [4, 12, 16, 20];



function checkAdult(age) {

    return age >= document.getElementById("ageToCheck").value;

}



function myFunction() {

    document.getElementById("demo").innerHTML = ages.some(checkAdult);

}

</script>


通过JavaScript制作table表格隔行变色

seo达人

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>隔行变色</title>

</head>

<body>

<table id="mytable" align="center" width="80%" border="1">

<tr bgcolor="#cccccc">

<td>aaa</td>

<td>aaa</td>

<td>aaa</td>

</tr>

<tr>

<td>bbb</td>

<td>bbb</td>

<td>bbb</td>

</tr>

<tr>

<td>ccc</td>

<td>ccc</td>

<td>ccc</td>

</tr>

</table>

<script type="text/javascript">

window.onload=function(){

//获取mytable中标签名为tr的字节点

mytable=document.getElementById("mytable");

trs=mytable.getElementsByTagName("tr");

len=trs.length;

flag=true;

for(i=0;i<len;i++){

if(flag){

//每隔一行设置背景色

var tr=document.getElementsByTagName("tr")[i].setAttribute("bgcolor","#cccccc");

flag=false;

}else{

flag=true;

}

}

}

</script>

</body>

</html>


js_判断浏览器内核与修改元素样式

前端达人

/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);



<script type="text/javascript">
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
//以下进行测试
if (Sys.ie) document.write('IE: ' + Sys.ie);
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
if (Sys.opera) document.write('Opera: ' + Sys.opera);
if (Sys.safari) document.write('Safari: ' + Sys.safari);
</script>


PC端只有Chrome有Safari字段吗?为什么不需要判断其他浏览器?
其实360,QQ等浏览器的userAgent字段也会带有Safari字段,但是由于他们基于Chrome二次开发的,所有也会携带有Chrome字段。
所以「匹配规则:拥有Safari字段,并且没有Chrome字段」就可以了。


接下来是修改元素样式





<html>
<head>
    <style>
     #a{
        width:700px;
        height:300px;
        font-size:50px;
        color:red;
        background-color:grey;
        z-index:2;
        position:absolute;
        top:1300px;
        left:200px;
        display:none;
    } 
    </style>
</head>
<body>
    <div id="a"></div>
</body>
<script type="text/javascript">
    //假设想修改display为block
    function modify(){
        //1.原生Js法
        var a= document.getElementById("a");
        a.style.display="block";
        //2.用JQuery的css方法
        var a =$("#a");
        a.css("display","block");
        //3.用JQuery的attr方法
        var a =$("#a");
        a.attr("style","display:block");
    }
</script>
</html>


这样就可以根据不同浏览器写出不同的样式适配啦



JS中数据类型转换

seo达人

JS中数据类型转换

目前为止,我了解到的JavaScript中共有6种类型。通过typeof关键字可以查看类型名称。



数据的类型:

字符串:若值为字符串,则显示为String。字符串使用单引号或双引号括起来。在控制台显示为黑色。

数字:若值为数字,则显示为Number。在控制台显示为蓝色。

布尔值:若值为布尔值,则显示为Boolean。它的值只有”true”和”false”。

对象:若值为对象,则显示为Object。

未定义:若值未定义,也就是仅仅声明,但未进行赋值,则显示为Undefined。

空值:若值为指向不引用对象的指针,则显示为Null,它与Undefined不同,以后慢慢深入了解。



以下表格详细写出了各种情况下相互转换的结果,可作为辅助记忆。



转换为字符串 转换为数字 转换为布尔值 转换为对象

undefined “undefined” NaN false throw TypeError

null “null” 0 false throw TypeError

true “true” 1 new Boolean(“true”)

false “false” 0 new Boolean(“false”)

“” 0 false new String("")

“1.2” 1.2 true new String(“1.2”)

“1.2a” NaN true new String(“1.2a”)

“aaa” NaN true new String(“aaa”)

0 “0” false new Number(0)

1 “1” true new Number(1)

NaN “NaN” false new Number(NaN)

Infinity “Infinity” true new Number(Infinity)

[] “” 0 true

[9] “9” 9 true

[“a”“b”] “a,b” NaN true

在Js中,数据类型可以相互转换,转换的方式有两种,隐式转换和强制转换,首先来说一些隐式转换。在进行代码书写时,要经常提醒自己所使用的元素是什么数据类型,在进行某些操作后是否会导致数据类型的变化,原因就是Js会对数据进行类型的隐式转换。



隐式转换举例:

(+)加法运算的隐式转换:加号两边只要出先了字符串,就自动将两者均转化为字符串,使两个字符串发生“拼接”,最后生成的结果也是一个字符串;如果前后都不是字符串,则转化为数字类型进行计算。



(-、*、/、%)其他算数运算的隐式转换:前后都转化为数字类型进行计算。



(!)逻辑非的隐式转换:他会将他后面的变量或表达式转换为布尔值。



(<,>)比较运算符的转换:如果前后存在一个数字,会对另一个转化为数字进行比较;如果前后均为字符串,会依次比较对应字符的编码大小,老大比老大,老二比老二,依次进行。



(&&,||)逻辑运算符的转换:先将前后都转化为布尔值再进行判断,要记住的是,只有undefined,null,0,””,NaN会转化成为false,其他都是true。



(== 、===)这里作为补充说明,null与Undefined相等但不全等,NaN与任何都不相等。



强制转换的方式:

1.转化为字符串

String(里面写待转化的内容):没什么好解释的,就是强制将你所看到的转化为你所看到的。

toString(里面写目标数字是几进制),写法为:待转化内容.toString(目标内容是几进制)。括号内不写时默认为10。

toFixed(保留小数的位数),写法为待转化内容.toFixed(保留小数的位数),存在精度误差。



2.转化为数字

Number(),只有所转化内容在肉眼看到的全是数字,才会正常转化;false会转化为0,true会转化为1;null会转化为0;undefined会转化为NaN;其他情况均为NaN。

parseInt(待转化内容,待转化内容的进制方式),与toString互为逆运算,不写的话默认为10。如果待转化内容为字符串,若以数字开头,可以从开始转换到字符前为止变成数值。布尔值,undefined,null经过转化均为NaN。

ParseFloat(),与上面一致,不赘述。



3.转化为布尔值

书写方式为Boolean(),如果上面的隐式转换你有好好看,这里很得不需要再写了。


密码验证 : 密码强度验证

前端达人

密码强度验证

需求

首先我们需要知道需求是什么? 这很重要!



要知道 我们写的一切逻辑都是建立在需求之上



当输入框聚焦时提示密码要求



当密码符合要求时 隐藏提示 并给予反馈



密码等级低时 提示密码等级为低



密码等级一般时 提示密码等级为中



密码等级高时 提示密码等级为高



当密码不符合要求时 重新打开提示



思考如何构建函数
通过上面的需求 你能想到的函数时什么?你能想到的逻辑又是什么?

首先 提示的显示隐藏我们可以用事件绑定或者事件监听来做

其次 我们需要利用正则来判断密码等级

当密码等级为低时 显示红色

当密码等级为中时 显示黄色

当密码等级为高时 显示绿色

最后 根据密码等级来渲染页面 也就是反馈给用户的样式

建议 :

在这里 尽量把每个函数的功能区分好 构思好

不仅要让自己能看懂 还要让别人能看懂

这样的代码才是好的代码 可读性更好 可维护性更高


实现功能 实现需求

HTML结构

在提示盒子的内部写3个div 不同等级给予不同颜色不同数量的提示

 密码 : <input type="text" id="ipt">
    <p id="p">请输入6-20位的带有数字字母或者特殊符号的密码</p>
    <div class="box">
        <span></span>
        <div></div>
        <div></div>
        <div></div>
    </div>


点击查看原图



不管样式行为再怎么花里胡哨 也一定要先把结构里要出现的元素写出来



CSS样式

由于考虑到等级分为三种 所以给提示盒子分3中不同的class类名

每一个类名对应的子元素的样式也不同

到js部分我们只需要操作class类名就可以了

   <style>
        *{
            margin : 0 ;
            padding : 0 ;
        }
        //提示盒子
        .box{
            position : absolute;
            top : 2px;
            left : 200px;
        }
        .box div,
        .box span{
            margin-right : 5px;
            width : 20px;
            height : 20px;
            float : left;
        }
        //低等级
        .box.low :nth-child(2){
            background : red;
        }
        //中等级
        .box.middle div{
            background : yellow;
        }
        .box.middle :last-child{
            background: #fff;
        }
        //高等级
        .box.high div{
            background : green;
        }
        //提示文字默认隐藏
        p{
            display : none;
        }
    </style>



20200315203557273.png

JS行为

 <script>
        //获取需要操作的元素
        let ipt = document.getElementById('ipt');
        let p = document.getElementById('p');
        let div = document.getElementsByClassName('box')[0];
        var tip = false; //聚焦显示提示的开关
        //添加聚焦事件
        ipt.addEventListener('focus' , () => {
            //由于存在用户输入正确的密码失焦再操作的可能 所以需要验证开关
            if(!tip) {
                p.style.display = 'block';
            }
            //默认选中文字 提升用户体验
            ipt.select();
        })
        //添加输入时的事件
        ipt.addEventListener('input' , () => {
            //拿到用户输入的密码字符串
            let str = ipt.value;
            //当密码不符合要求时 要及时给予反馈 及时清除样式
            if(str.length < 6 ||str.length > 20 || /[^(\da-zA-Z\_\#\@\$\^\%\*\&\!\~\+\-)]/.test(str) || str === "") {
                p.style.display = 'block';
                removeClass(div);
                div.children[0].innerHTML = "";
                tip = true;
                //如果不符合要求 就没必要判断等级了 直接结束判断
                return false;
            }else{
                p.style.display = 'none';
            }
            //判断密码等级
            let res = level(str);
            //根据等级添加样式
            randerLevel(res);
        })
        //判断密码等级函数
        function level (str) {
            let level = 0;
            //当用户输入的字符串符合一定规则 让等级+1
            if(/\d+/.test(str)) {
                level ++;
            }
            if(/[a-zA-Z]+/.test(str)) {
                level ++;
            }
            if(/[\_\#\@\$\^\%\*\&\!\~\+\-]+/.test(str)) {
                level ++;
            }
            return level;
        }
        //添加样式函数
        function randerLevel (level) {
            //在添加样式前先清空样式
            removeClass(div);
            div.children[0].innerHTML = "";
            //根据等级添加对应的类名
            switch (level) {
                case 1 :
                    div.children[0].innerHTML = '低';
                    //元素存在不止一个类名 用 += 更好
                    div.className += ' low';
                    break;
                case 2 :
                    div.children[0].innerHTML = '中';
                    div.className += ' middle';
                    break;
                case 3 :
                    div.children[0].innerHTML = '高';
                    div.className += ' high';
                    break;
            }
        }
        //去等级类名函数
        function removeClass(ele){
            let reg = /low|middle|high/g;
            if(reg.test(ele.className)) {
                //不要忘记把值赋回去 replace返回的是新字符串
                ele.className = ele.className.replace(reg , "");
            }
        }
    </script>

当密码等级为低时 给予红色反馈

2020031520385174.png


  • 当密码等级为中时 给予黄色反馈
    20200315203928450.png
  • 当密码等级为高时 给予绿色反馈
    20200315203952860.png
  • 当密码长度太短或太长时 不给予颜色反馈 给予文字反馈
20200315204030964.png


————————————————
版权声明:本文为CSDN博主「豆浆不好喝」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45178648/article/details/104885417

HTML 学习总结2 框架 表单

前端达人

这是HTML学习总结系列的第二篇,第一篇在这里:

HTML 学习总结1入门 基本概念、格式 文字标签 图片标签 链接标签 表格标签 注释

这次的学习内容相较第一次分类少,但是比较杂。



框架集标签

框架标签是将网页设置成网页框架的一种双标签,被设计成框架的网页被切分成若干区域,没有实际的内容,只当做框架用于镶嵌其它的网页。

那么,这个标签是:

<frameset></frameset>

框架集标签的属性

使用的时候需要将HTML文件中的body标签部分替换为框架标签,写成这样:



<html>
    <head></head>
    <frameset rows="500,*" border="3" noresize="noresize">
    </frame>
</html>

看上面的代码,用frameset替换掉body不难理解,毕竟我们约定做框架的网页不具有实体内容
接着,这里提到了框架标签的三个属性,分别为:

rows/cols 框架的分行或分列
border 分隔框的宽度
noresize 大小是否可调
现在来分别解释一下

第一个,rows 或cols 属性,代表了框架的分行或分列的情况,在引号内书写该属性的值的时候,不需要指明分成几栏,只需要指明每一栏占据的宽度或高度(单位为像素)并使用逗号隔开。浏览器在解析的时候会计算到底分成了几栏。另外,不指定宽度而使其占据剩余位置时,可以使用通配符 “ * ”。

第二个,border 属性,代表了分隔框的宽度,这是属性的数值单位是像素。所以如果你不想加入边框,则可以将它设置为零。

第三个,noresize 属性,表示我们的框架的大小是否可调,frameset标签默认为大小可调,当用户鼠标移动到边框上时,他可以拖拽改变大小。所以如果不想让用户随意改变框架大小,那么可以选择使用这个属性 (当然,也可以选择把边框的宽度设为零,让他找不到)。 这个属性的值同属性名称一样。

最后还需要说明的是:框架集标签是可以进行嵌套的,也就是说,在已经分出来的框架中,我们可以借着分栏。

在框架内镶嵌网页
刚刚我们使用 frameset 标签将网页变成框架并划分成了若干区域,每一个区域都是一个单独的可显示页面的子网页(笔者起的名)。现在,我们需要在这些区域内为它镶嵌上一个网页,这需要用到frame这个单标签在框架下添加网页,它的写法如下:

<frame src="...." name="...." />
1
这里可以看到 frame 标签的两个属性; src 和 name 。它们分别代表着添置连接(这是一个超链接,网页,HTML文件,图片等都是可以的。有关超链接的信息,可参照上一篇学习总结或者问问度娘 ),以及框架名称。

框架的命名,很主要的一个原因在于可以重复利用一个框架,即在其他标签使用时,可以在某个框架上显示相应内容。还记得上一篇中,我们提到的链接标签 target 属性中的 “某框架名称” 这个值吗?在为框架命名后,就可以使用上述的 target 用法,将打开的网页放在某个框架中了。

综上,举个例子:

先来创造一个带有嵌套的框架
<!--frame-->
<html>
    <head></head>
    <frameset rows="200,*" border="5" noresize="noresize">
        <frame src="title.html" name="title" />
        <frameset cols="200,*">
            <frame src="selection_bar.html" />
            <frame name="output_page" />
        </frameset>
    </frameset>
</html>



<!--title-->
<html>
    <head></head>
    <body>
        <font size="7" color="blue">
            The test page
        </font>
    </body>
</html>



<!--selection_bar-->
<html>
    <head></head>
    <body>
        <font size="5" color="red">
            Please select websites.
        </font>
        <br /><br />
        <a href="http://www.baidu.com" target="output_page"/>百度一下<br /><br />
        <a href="https://www.csdn.net" target="output_page"/>CSDN <br /><br />
    </body>
</html>

最后来看下结果:

点击查看原图


点击查看原图点击查看原图




vue父组件向子组件传值

前端达人

非常简单,相信大家一看就懂

复制到浏览器即可使用,注意别忘了引入vue哦


<div id="app">
    <div>{{pmsg}}</div>
    <menu-item :title='ptitle' :content='ptitle'></menu-item>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
    //父组件向子组件传值-基本使用
    Vue.component('menu-item', {
        props: ['title', 'content'],
        data: function() {
            return {
                msg: '子组件本身的数据'
            }
        },
        template: `<div>
      <p>{{msg}}</p>
      <p>{{title}}</p>
      <p>{{content}}</p>
      </div>`
    });
    var vm = new Vue({
        el: '#app',
        data: {
            pmsg: '父组件中内容',
            ptitle: '动态绑定属性'
        }
    });
</script>
————————————————
版权声明:本文为CSDN博主「温柔的坚持」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43745003/article/details/104908639

JS的原型介绍及原型的继承

前端达人

前言

在学习JS中的原型,原型链,继承这些知识之前,我们先学习下基础知识:函数和对象的关系。

我们一直都知道,函数也是对象的一种,因为通过instanceof就可以判断出来。但是函数和对象的关系并不是简单的包含和被包含的关系,这两者之间的关系还是有点复杂的。接下来我们就来捋一捋。



首先,阐述一点,对象都是通过函数创建的

对于下面这种类型的代码,一般叫做“语法糖”

var obj = {a:10,b:20};
var arr = [5, 'x', true];



但是,其实上面这段代码的实质是下面这样的:


//var obj = { a: 10, b: 20 };
//var arr = [5, 'x', true];

 var obj = new Object();
 obj.a = 10;
 obj.b = 20;

 var arr = new Array();
 arr[0] = 5;
 arr[1] = 'x';
 arr[2] = true;



而Object和Array都是函数,可以自己用typeof函数进行验证。
所以,可以得出:对象都是通过函数创建的

正文
说完了前言,接下来我们进入正题。

原型prototype
在前言中,我们说了函数也是一种对象,所以函数也是属性的集合,同时,也可以对函数进行自定义属性。
每个函数都有一个属性——prototype。这个prototype的属性值是一个对象(属性的集合),默认只有一个叫做constructor的属性,指向这个函数本身.

“隐式原型”proto
我们先看一段非常常见的代码:
function Fn() { }
   Fn.prototype.name = '张三';
    Fn.prototype.getAge = function () {
       return 12;
};
   var fn = new Fn();
   console.log(fn.name);
   console.log(fn.getAge ());

即,Fn是一个函数,fn对象是从Fn函数new出来的,这样fn对象就可以调用Fn.prototype中的属性。

但是,因为每个对象都有一个隐藏的属性——“proto”,这个属性引用了创建这个对象的函数的prototype。即:fn.proto === Fn.prototype
那么,这里的_proto_到底是什么呢?

其实,这个__proto__是一个隐藏的属性,javascript不希望开发者用到这个属性值,有的低版本浏览器甚至不支持这个属性值。

var obj = {};
console.log(obj.__proto__);

每个对象都有一个_proto_属性,指向创建该对象的函数的prototype。

构造函数、原型、实例之间的关系
实例,原型对象,构造函数,三者之间的关系:

(1) 实例有__proto__属性指向原型对象

(2) 原型对象有constructor指针指向构造函数

(3)构造函数又有prototype属性指向原型对象
点击查看原图


实例和原型关系检测

isPrototypeOf()函数,用于检测两个对象之间似乎否存在原型关系,使用方法如下:

  // 查看 Fn 的 prototype 对象,是否是 f 原型
  Fn.prototype.isPrototypeOf(f);   



 //// 查看 f 对象是否是构造函数 Fn 的实例
 //console.log(f instanceof Fn); 
 //// 查看 f 对象是否是构造函数 Fn 的实例    
 //console.log(f instanceof Object); 

    function Fn(){}
    function Fun(){}
    var f = new Fn();
    console.log( f.__proto__ === Fn.prototype );            // t

    console.log( Fn.prototype.isPrototypeOf(f) );           // t
    console.log( Fun.prototype.isPrototypeOf(f) );          // f
    console.log( Object.prototype.isPrototypeOf(f) );       // t

    console.log( f instanceof Fn );         // t
    console.log( f instanceof Fun );        // f
    console.log( f instanceof Object );     // t
//两种使用,如果是返回ture,如果不是返回false;
//注意:instanceof运算符右侧为构造函数,并且js中所有原型都来自Object构造函数。

JS解析器访问属性顺序
当访问实例 f 的属性或方法时,会先在当前实例对象 f 中查找,如果没有,则沿着__proto__继续向上寻找,如果找到最顶头的Object还是找不到,则会抛出undefined。如果在实例中找到,或某层原型中找到,就会读取并使用,同时停止向上找寻。
由此可见,解析器的解析顺序遵循就近原则,如果在最近的位置发现属性存在,便不会继续向上找寻。

原型的应用
数组去重:

Array.prototype.noRepeat = function(){
    var m = [];
    for(var i=0;i<this.length;i++){
        if(m.indexOf(this[i]) == -1){
            m.push(this[i]);
        }
    }
    return m;
}
var arr = [3,4,5,6,7,6,5,4,3,2,1];
var res = arr.noRepeat();
console.log(res);

var arr1 = ["a","b","c","b","a"];
var res1 = arr1.noRepeat();
console.log(res1);



function Parent(){

}
Parent.prototype.show = function(){
    console.log("哈哈哈");
}

function Child(){

}
for(var i in Parent.prototype){
    Child.prototype[i] = Parent.prototype[i];
}
Child.prototype.show = function(){
    console.log("hello");
}

var p = new Parent();
p.show();
console.log(p.name);

var c = new Child();
c.show();
console.log(c.name);



————————————————
版权声明:本文为CSDN博主「zyfacd」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zyfacd/article/details/104909948

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档