流程控制语句和this及自定义属性

本文详细介绍了JavaScript中的流程控制语句,包括顺序结构、选择结构(分支结构:if-else, switch)、循环结构(for, while, do-while)。重点讲解了for循环的双重使用,用于遍历数组和生成标签。同时,解释了while和do-while循环的差异,以及break和continue在循环中的作用。此外,还讨论了JSON数据的操作,如属性访问和for-in循环的使用。最后,提到了this关键字在事件处理函数中的应用场景以及自定义属性的设置。

流程控制语句

  • 顺序结构

  • 选择结构(分支结构):if if-else if-else if -else switch

  • 循环结构(for while do-while for-in)

2.1for循环

for(初始化循环变量;循环判断条件;更新循环变量){
  重复执行的代码(循环体)
}

2.2双重for循环

  • 基础用法

<script>
        // 双重for循环
        for (var i = 0; i < 5; i++) {//i = 0 1 2 3 4
            for (var j = 0; j < 3; j++) {
                console.log("文字");
            }
        }
        /*
            i=0
                j=0 1 2 
            i=1
                j=0 1 2 
            i=2
                j=0 1 2 
            i=3
                j=0 1 2
            i=4
                j=0 1 2
            i=5
        */
​
​
​
​
        //双重for循环数组
        var arr = [
            ["哈哈", "呵呵", "嘻嘻", null],//4
            ["1", "2", "3"],//3
            ["周一", "周二", "周三"],//3
            [true, false]//3
        ];
        // console.log(arr[0][0]);//"哈哈"
        // console.log(arr[0][1]);//"呵呵"
        // console.log(arr[0][2]);//"嘻嘻"
​
        // console.log(arr[1][0]);//"1"
        // console.log(arr[1][1])//"2"
        // console.log(arr[1][2])//"3"
​
        // console.log(arr[2][0])//"周一"
        // console.log(arr[2][1])//"周二"
        // console.log(arr[2][2])//"周三"
​
​
        for (var i = 0; i < 3; i++) {//外层循环 i = 0 1 2
            for (var j = 0; j < 3; j++) {
                // console.log(i, j);
                console.log(arr[i][j]);
            }
        }
​
        //循环次数根据length确定
        for (var i = 0; i < arr.length; i++) {//外层循环 i = 0 1 2
            for (var j = 0; j < arr[i].length; j++) {
                // console.log(i, j);
                console.log(arr[i][j]);
            }
        }
    </script>
  • 双重for循环生成标签

<script>
        // 模拟后台的数据结构
        var arr = [
            ["唐朝诡事录", "诛仙", "庆余年", "雪中悍刀行", "仙剑奇侠传3", "行尸走肉"],
            ["流浪地球", "绿皮书", "肖申克的救赎", "寄生虫", "釜山行", "谋杀1"],
            ["火影忍者", "蜡笔小新", "东京喰种", "名侦探柯南"],
            ["火影忍者", "蜡笔小新", "东京喰种", "名侦探柯南1"],
        ]
        // arr[0] 给第一个ul  arr[1]  给第二个ul  arr[2]  给第三个ul
        var oUl = document.getElementsByTagName("ul");
​
​
        // for (var i = 0; i < arr[0].length; i++) {
        //     oUl[0].innerHTML += "<li>" + arr[0][i] + "</li>";
        // }
​
        // for (var i = 0; i < arr[1].length; i++) {
        //     oUl[1].innerHTML += "<li>" + arr[1][i] + "</li>";
        // }
​
        // for (var i = 0; i < arr[2].length; i++) {
        //     oUl[2].innerHTML += "<li>" + arr[2][i] + "</li>";
        // }
​
        // 双重for循环
        for (var j = 0; j < arr.length; j++) {//j = 0 1 2
            for (var i = 0; i < arr[j].length; i++) {
                oUl[j].innerHTML += "<li>" + arr[j][i] + "</li>";
            }
        }
​
        /*
            j = 0
                i= 0 i<arr[0].length i++
                    oul[0].inerHTML = "<li>"+arr[0][i]+"</li>"
            j = 1
                i=0 i<arr[1].length i++
                     oul[1].inerHTML = "<li>"+arr[1][i]+"</li>"
        */
    </script>

2.3while循环

  • 基础语法

  1.初始化循环变量
            while(循环结束条件){
                重复执行的代码(循环体)
                更新循环条件
            }
  • 基础使用

 <script>
        for (var i = 1; i <= 10; i++) {
            console.log(i);
        }
​
        //输出1-10之间的数
        var i = 1;
        while (i <= 10) {
            console.log("while", i);
            i++;
        }
​
    </script>

2.4do-while循环

  • 基础语法

 1.初始化循环变量;
     do{
          循环体;
           更新循环变量;
    }while(循环判断条件)
  • 使用

 <script>
        //1-10之间的数
        var i = 1;
        do {
            console.log(i);
            i++
        } while (i <= 10)
    </script>
  • ==while和do-while的区别==

while:先判断后执行,如果初始条件为false  循环体一次也不执行
do-while:先执行后判断,如果初始条件为false 循环体至少会执行一次

2.5break和continue

  • break 结束整个循环

  • continue 结束本次循环

 <script>
        for (var i = 1; i <= 10; i++) {
            // 吃到第5个水饺的时候 碗里面进了一个苍蝇
            if (i == 5) {
                console.log("掉进去一个苍蝇");
                break;//结束后面整个循环
            }
            console.log("这是第" + i + "个水饺")
        }
​
        for (var i = 1; i <= 10; i++) {
            if (i == 5) {
                console.log("这个水饺掉了");
                continue;//结束本次循环
            }
            console.log("这是第" + i + "个水饺");
        }
    </script>

3.json数据和for-in

3.1json数据

  • JSON数据/object类型数据/对象类型:一组无序的,没有长度的数据

属性值/value/键值:可以是任意数据类型
{
  "属性名":属性值,
  "属性名":属性值,
   属性名:属性值,
   key:value,
   键名:键值
}
建议:属性名带""  值和值之间用逗号隔开
  • 获取属性值:obj.属性名

script>
        /* JSON数据/object类型数据/对象类型:一组无序的,没有长度的数据 */
        var obj = {
            "name": "小候老师",
            "age": 18,
            isOn: true,
            skill: ["前端", "讲课", "做饭"],
            a: undefined,
            b: null,
            c: {},
            d: function () { }//函数在对象中不叫函数,叫方法
        }
​
        console.log(obj);//
        console.log(obj.length);//undefined 没有长度
​
        //获取对象中的属性值  对象名.属性名
        console.log(obj.name);//"小候老师"
        console.log(obj.skill);//["前端", "讲课", "做饭"]
        console.log(obj.b);//null
    </script>
  • ==注意1:obj后面跟的就是属性名,没有变量的概念 如果跟的是变量 用[]代替 对象名[变量名]==

  • ==注意2:注意2:style中碰见变量,也是[]代替==

        //注意1:obj后面跟的就是属性名,没有变量的概念 如果跟的是变量 用[]代替  对象名[变量名]
        var a1 = "name";
        console.log(obj[a1]);//小候老师
​
        //注意2:style中碰见变量 也是[]代替
        var oDiv = document.getElementsByTagName("div")[0];
        //获取样式  标签.style.样式名
        console.log(oDiv.style.width);//100px
        var a2 = "width";
        console.log(oDiv.style[a2]);
  • 设置对象中的属性

        var obj1 = {
            age: 20,
        };
        //2.直接设置属性名  对象名.属性名 = 值;
        obj1.name = "王昭君";
        obj1.age = 30;
        console.log(obj1);

3.2for-in

  • 基础语法

对象:是一组无序的 没有长度的数据  
​
for-in:遍历对象
for(var 变量名 in 循环对象){
  循环体
}
  <script>
        var obj = {
            "name": "小候老师",
            "age": 18,
            "isOn": true,
        }
        //for-in 遍历对象 根据对象中的值自动循环
        for (var key in obj) {//key=name  age isOn
            console.log(key);
            // 对象.属性名
            console.log(obj[key]);
        }
    </script>

4.this

4.1为什么使用this

<script>
        // 点击谁 就将谁的文本内容输出
        // 批量添加点击事件
        var oLi = document.getElementsByTagName("li");
        console.log(oLi.length);//集合标签的长度
        for (var i = 0; i < oLi.length; i++) {// i = 0 1 2 3....9
            oLi[i].onclick = function () {
                console.log(i);//10
                //输出文本内容
                // console.log(oLi[i].innerHTML);
            }
        }
        //i = 10
        /* 
            i为什么嘛输出10
                因为for循环只是添加事件,并不会执行事件中的代码
        */
    </script>

4.2this的概念

  • this:这个

  • 概念:在不同的地方 代表的值不同 取决于当前函数被调用时所处的环境

  • 事件处理函数:标签.事件类型= function(){ }

  • 在事件处理函数中使用this this指向当前触发事件的对象

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <script>
        var btn = document.getElementsByTagName("button");
        // 在事件处理函数中  this指向当前触发事件的对象  点谁指向谁
        btn[0].onclick = function () {
            console.log(this);
        }
        btn[1].onclick = function () {
            console.log(this);
        }
    </script>

5.自定义属性

  • 属性分类

    • 固有属性 本身自带的属性 class id style src alt等等

      • 操作固有属性:标签.属性值名

    • 自定义属性

      <div class="box" id="wrap" a="这是一个自定义属性" b="123"></div>
        <script>
            var oDiv = document.getElementsByTagName("div")[0];
            // 1.操作固有属性 取赋值一体化  标签.属性名  class需要改成className
            console.log(oDiv.className);//"box"
            console.log(oDiv.id);//"wrap"
            oDiv.className = "box1";
            //2.如何设置自定义属性
            //2.1 直接在标签上添加属性,在结构上能看到  但是在js中无法获取
            console.log(oDiv.a);//undefined
            console.log(oDiv.b);//undefined
            // 2.2通过js设置  在结构上看不到  但是可以在js中使用  标签.属性名 = 值
            oDiv.c = "456";
            console.log(oDiv.c);//456
        </script>

5.1单组开关灯效果

  • 单组开关等实现步骤

    • 现象:一个事件中有2种状态,此时就可以使用开关灯效果

<body>
    <img src="./img/dark.jpg" alt="">
    <script>
        var oImg = document.getElementsByTagName("img")[0];
        //如果没有判断条件  就自己创造判断条件
        var tag = true;//true 显示开灯bright.jpg  false显示关灯dark.jpg
        oImg.onclick = function () {
            // 为什么不能用src来做判断
            console.log(oImg.src);//不要用src做判断
            if (tag == true) {
                oImg.src = "./img/bright.jpg";
                // 一定要更改tag的值 方便下次做判断
                tag = false;
            } else {
                oImg.src = "./img/dark.jpg";
                tag = true;
            }
        }
    </script>
</body>

5.2多组开关灯效果

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <script>
        /* 
            问题1:在点击事件中,可以拿到oDiv[i]吗
            解决: i的值始终都是4  所以用this代替oDiv[i]
        */
        /* 
             问题2:在交叉点击div的时候  出现bug
             解决:所有的div共用了一个判断条件tag,给每个div都单独设置一个判断条件
        */
        // 循环添加点击事件
        var oDiv = document.getElementsByTagName("div");
        //给每个div都添加一个判断条件  添加自定义属性tag=true
        // oDiv[0].tag = true;
        // oDiv[1].tag = true;
        // oDiv[2].tag = true;
        // oDiv[3].tag = true;
        
        // for (var i = 0; i < oDiv.length; i++) {
        //     oDiv[i].tag = true;
        // }
        for (var i = 0; i < oDiv.length; i++) {
            oDiv[i].tag = true;
            oDiv[i].onclick = function () {
                // console.log(i);//4 拿到的是i最后一次的值
                // console.log(oDiv[i]);//undefined
                if (this.tag) {
                    this.style.height = "100px";
                    this.tag = false;
                } else {
                    this.style.height = "20px";
                    this.tag = true;
                }
            }
        }
    </script>
<think>我们讨论的是在Android自定义View中如何获取string类型int类型的属性。通常,我们在自定义View时需要定义自定义属性,然后在XML布局中使用这些属性,并在自定义View的代码中获取这些属性的值。 步骤: 1. 在res/values/attrs.xml中定义自定义属性。 2. 在XML布局中使用自定义属性。 3.自定义View的代码中获取属性值。 下面我们将详细说明如何获取stringint类型的属性值。 假设我们有一个自定义属性如下(在attrs.xml中定义): ```xml <resources> <declare-styleable name="MyCustomView"> <attr name="customString" format="string" /> <attr name="customInteger" format="integer" /> </declare-styleable> </resources> ``` 然后,我们在布局XML中使用这个自定义属性: ```xml <com.example.myapp.MyCustomView android:layout_width="match_parent" android:layout_height="match_parent" app:customString="Hello, World!" app:customInteger="123" /> ``` 现在,在自定义View的代码中,我们需要在构造函数中获取这些属性值。 我们将分别展示如何获取stringint类型的属性值。 注意:自定义View的构造函数通常有三个,我们需要在带有AttributeSet参数的那个构造函数中获取属性值。 代码如下: </think>在 Android 自定义 View 中获取 string int 类型属性是一个核心开发技能,以下是完整的解决方案代码实现: ### 一、属性定义 (res/values/attrs.xml) 首先定义自定义属性: ```xml <resources> <!-- 自定义属性集合 --> <declare-styleable name="CustomTextView"> <!-- 字符串类型属性 --> <attr name="customText" format="string"/> <!-- 整型类型属性 --> <attr name="textStyle" format="integer"/> <attr name="maxLines" format="integer"/> <!-- 枚举类型属性 (本质上也是int) --> <attr name="textAlignment"> <enum name="left" value="0"/> <enum name="center" value="1"/> <enum name="right" value="2"/> </attr> </declare-styleable> </resources> ``` ### 二、布局中使用 (XML) ```xml <com.example.app.CustomTextView android:layout_width="match_parent" android:layout_height="wrap_content" app:customText="@string/app_name" <!-- 字符串资源 --> app:customText="Hello World" <!-- 硬编码字符串 --> app:textStyle="1" <!-- 整型值 --> app:maxLines="3" <!-- 整型值 --> app:textAlignment="center" <!-- 枚举值 --> /> ``` ### 三、Java/Kotlin 实现获取属性值 #### Java 实现: ```java public class CustomTextView extends TextView { private String customText; private int maxLines; private int textAlignment; public CustomTextView(Context context) { super(context); init(null); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); init(attrs); } private void init(AttributeSet attrs) { if (attrs == null) return; // 获取自定义属性集合 TypedArray ta = getContext().obtainStyledAttributes( attrs, R.styleable.CustomTextView ); try { // 获取字符串属性(两种获取方式) customText = ta.getString(R.styleable.CustomTextView_customText); // 获取整型属性(带默认值) maxLines = ta.getInteger(R.styleable.CustomTextView_maxLines, 1); // 获取枚举属性 textAlignment = ta.getInt( R.styleable.CustomTextView_textAlignment, 0 // 默认左对齐 ); // 处理获取到的值 setText(customText); setMaxLines(maxLines); setTextAlignment(convertAlignment(textAlignment)); } finally { ta.recycle(); // 必须回收TypedArray } } private int convertAlignment(int align) { switch(align) { case 0: return TEXT_ALIGNMENT_TEXT_START; case 1: return TEXT_ALIGNMENT_CENTER; case 2: return TEXT_ALIGNMENT_TEXT_END; default: return TEXT_ALIGNMENT_TEXT_START; } } } ``` #### Kotlin 实现: ```kotlin class CustomTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : TextView(context, attrs, defStyleAttr) { init { attrs?.let { val ta = context.obtainStyledAttributes( it, R.styleable.CustomTextView ) try { // 获取字符串属性 val customText = ta.getString(R.styleable.CustomTextView_customText) // 获取整型属性(带默认值) val maxLines = ta.getInteger(R.styleable.CustomTextView_maxLines, 1) // 获取枚举属性 val textAlignment = ta.getInt( R.styleable.CustomTextView_textAlignment, 0 // 默认左对齐 ) // 应用属性值 text = customText setMaxLines(maxLines) textAlignment = when(textAlignment) { 0 -> TEXT_ALIGNMENT_TEXT_START 1 -> TEXT_ALIGNMENT_CENTER 2 -> TEXT_ALIGNMENT_TEXT_END else -> TEXT_ALIGNMENT_TEXT_START } } finally { ta.recycle() } } } } ``` ### 四、关键概念解释 1. **TypedArray 处理流程**: ```mermaid graph LR A[obtainStyledAttributes] --> B[获取属性值] B --> C[处理属性值] C --> D[recycle释放资源] ``` 2. **属性获取方法对比**: | 方法 | 返回类型 | 特点 | |--------------------------|----------|--------------------------------| | `getString()` | String | 支持资源硬编码字符串 | | `getInteger()` | int | 直接返回XML中的整数 | | `getInt()` | int | 适合枚举值标志位 | | `getDimensionPixelSize()`| int | 将dp/sp转换为像素值 | | `getResourceId()` | int | 获取资源ID(如drawable/mipmap)| 3. **常见问题解决方案**: - **属性未生效**:检查命名空间 `xmlns:app="http://schemas.android.com/apk/res-auto"` - **类转换异常**:确保XML属性类型获取方法匹配 - **内存泄漏**:务必调用 `ta.recycle()` 释放资源 - **枚举处理**:使用 `getInt()` + switch 处理枚举属性 ### 五、高级用法:动态属性解析 ```java // 动态检查属性是否存在 public boolean hasAttribute(TypedArray ta, int index) { return ta.hasValue(index) || ta.hasValueOrEmpty(index); } // 获取属性值并记录来源 private void processAttribute(TypedArray ta, int index) { if (ta.hasValue(index)) { int type = ta.getType(index); switch (type) { case TypedValue.TYPE_STRING: String sValue = ta.getString(index); Log.d("AttrDebug", "String value: " + sValue); break; case TypedValue.TYPE_INT_DEC: case TypedValue.TYPE_INT_HEX: int iValue = ta.getInteger(index, 0); Log.d("AttrDebug", "Integer value: " + iValue); break; case TypedValue.TYPE_REFERENCE: int resId = ta.getResourceId(index, 0); Log.d("AttrDebug", "Resource ID: " + resId); break; } } } ``` ### 六、属性继承与样式处理 ```java // 支持在theme中定义默认值 public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes( attrs, R.styleable.CustomTextView, defStyleAttr, // 使用传入的默认样式 R.style.DefaultCustomTextViewStyle // 默认样式 ); // ... 处理属性 } // 在styles.xml中定义默认样式 <style name="DefaultCustomTextViewStyle"> <item name="customText">@string/default_text</item> <item name="maxLines">2</item> <item name="textAlignment">center</item> </style> ``` ### 七、性能优化建议 1. **缓存属性索引**: ```java private static final int[] ATTRS = { R.styleable.CustomTextView_customText, R.styleable.CustomTextView_maxLines, R.styleable.CustomTextView_textAlignment }; // 在初始化时使用 TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS); String text = ta.getString(0); ``` 2. **延迟解析**:仅在需要时解析复杂属性 3. **属性变更监听**: ```java public void setCustomText(String text) { this.customText = text; invalidate(); // 触发重绘 requestLayout(); // 需要时重新布局 } ``` **总结**:在自定义 View 中获取 string int 属性核心是使用 `TypedArray` 的正确 API,注意资源回收类型匹配。处理枚举类型时使用 `getInt()` 配合 switch 语句,字符串属性优先使用资源引用支持多语言。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值